diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index d70df4c5c5e..12e8518a2b0 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -73,7 +73,9 @@ class OrlikSolomonAlgebra(CombinatorialFreeModule): 14 sage: G = OS.algebra_generators() sage: M.broken_circuits() - frozenset({frozenset({1, 2, 3})}) + SetSystem of 1 sets over 4 elements + sage: M.broken_circuits()[0] + frozenset({1, 2, 3}) sage: G[1] * G[2] * G[3] OS{0, 1, 2} - OS{0, 1, 3} + OS{0, 2, 3} diff --git a/src/sage/geometry/hyperplane_arrangement/arrangement.py b/src/sage/geometry/hyperplane_arrangement/arrangement.py index fa526356278..17ae3a25738 100644 --- a/src/sage/geometry/hyperplane_arrangement/arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/arrangement.py @@ -1955,7 +1955,7 @@ def skip(b_list): lhs = matrix(R, d, d) rhs = vector(R, d) vertices = set() - for indices in M.independent_r_sets(d): + for indices in M.independent_sets(d): for row, i in enumerate(indices): lhs[row] = A_list[i] b_list = [b_list_list[i] for i in indices] diff --git a/src/sage/matroids/advanced.py b/src/sage/matroids/advanced.py index c401afc7699..65b30f1bc36 100644 --- a/src/sage/matroids/advanced.py +++ b/src/sage/matroids/advanced.py @@ -1,5 +1,5 @@ r""" -Advanced matroid functionality. +Advanced matroid functionality This module collects a number of advanced functions which are not directly available to the end user by default. To import them into the main namespace, @@ -10,19 +10,20 @@ This adds the following to the main namespace: - Matroid classes: - - :class:`MinorMatroid ` - - :class:`DualMatroid ` - - :class:`RankMatroid ` + + - :class:`BasisMatroid ` - :class:`CircuitsMatroid ` - :class:`CircuitClosuresMatroid ` - - :class:`BasisMatroid ` + - :class:`DualMatroid ` - :class:`FlatsMatroid ` + - :class:`GraphicMatroid ` - :class:`LinearMatroid ` - :class:`RegularMatroid ` - :class:`BinaryMatroid ` - :class:`TernaryMatroid ` - :class:`QuaternaryMatroid ` - - :class:`GraphicMatroid ` + - :class:`MinorMatroid ` + - :class:`RankMatroid ` Note that you can construct all of these through the :func:`Matroid() ` function, which is @@ -30,6 +31,7 @@ for faster code (e.g. if your code calls ``Matroid()`` frequently). - Other classes: + - :class:`LinearSubclasses ` - :class:`MatroidExtensions ` @@ -39,30 +41,34 @@ :meth:`Matroid.extensions() `. - Useful functions: + - :func:`setprint() ` - :func:`newlabel() ` - :func:`get_nonisomorphic_matroids() ` - - :func:`lift_cross_ratios() ` - - :func:`lift_map() ` + - :func:`lift_cross_ratios() ` + - :func:`lift_map() ` + - :func:`cmp_elements_key() ` AUTHORS: - Stefan van Zwam (2013-04-01): initial version """ -import sage.matroids.matroid -import sage.matroids.basis_exchange_matroid -from .minor_matroid import MinorMatroid -from .dual_matroid import DualMatroid -from .rank_matroid import RankMatroid -from .circuits_matroid import CircuitsMatroid -from .circuit_closures_matroid import CircuitClosuresMatroid -from .basis_matroid import BasisMatroid -from .flats_matroid import FlatsMatroid -from .linear_matroid import LinearMatroid, RegularMatroid, BinaryMatroid, TernaryMatroid, QuaternaryMatroid -from .utilities import setprint, newlabel, get_nonisomorphic_matroids, lift_cross_ratios, lift_map -from . import lean_matrix -from .extension import LinearSubclasses, MatroidExtensions -from .union_matroid import MatroidUnion, MatroidSum, PartitionMatroid +from sage.matroids import matroid, basis_exchange_matroid, lean_matrix + +from sage.matroids.basis_matroid import BasisMatroid +from sage.matroids.circuits_matroid import CircuitsMatroid +from sage.matroids.circuit_closures_matroid import CircuitClosuresMatroid +from sage.matroids.dual_matroid import DualMatroid +from sage.matroids.flats_matroid import FlatsMatroid +from sage.matroids.linear_matroid import LinearMatroid, RegularMatroid, BinaryMatroid, TernaryMatroid, QuaternaryMatroid +from sage.matroids.minor_matroid import MinorMatroid +from sage.matroids.rank_matroid import RankMatroid +from sage.matroids.union_matroid import MatroidUnion, MatroidSum, PartitionMatroid + +# lazy import of GraphicMatroid for modularization purposes from sage.misc.lazy_import import lazy_import lazy_import('sage.matroids.graphic_matroid', 'GraphicMatroid') + +from sage.matroids.extension import LinearSubclasses, MatroidExtensions +from sage.matroids.utilities import setprint, newlabel, get_nonisomorphic_matroids, lift_cross_ratios, lift_map, cmp_elements_key diff --git a/src/sage/matroids/all.py b/src/sage/matroids/all.py index 5a9a4805e41..e40ab089e1c 100644 --- a/src/sage/matroids/all.py +++ b/src/sage/matroids/all.py @@ -6,8 +6,6 @@ install_doc(__package__, __doc__) from sage.misc.lazy_import import lazy_import -# from constructor import Matroid -# import matroids_catalog as matroids lazy_import('sage.matroids.constructor', 'Matroid') lazy_import('sage.matroids', 'matroids_catalog', 'matroids') del lazy_import diff --git a/src/sage/matroids/basis_exchange_matroid.pxd b/src/sage/matroids/basis_exchange_matroid.pxd index 6bcc9e0236e..dc4b4aeb114 100644 --- a/src/sage/matroids/basis_exchange_matroid.pxd +++ b/src/sage/matroids/basis_exchange_matroid.pxd @@ -1,6 +1,5 @@ from sage.data_structures.bitset cimport * from sage.data_structures.bitset_base cimport bitset_t, bitset_s - from sage.matroids.matroid cimport Matroid from sage.matroids.set_system cimport SetSystem @@ -38,47 +37,43 @@ cdef class BasisExchangeMatroid(Matroid): cdef bint _set_current_basis(self, F) noexcept - cpdef groundset(self) - cpdef groundset_list(self) + cpdef frozenset groundset(self) + cpdef list groundset_list(self) cpdef full_rank(self) cpdef full_corank(self) cpdef basis(self) cpdef _move_current_basis(self, X, Y) - cpdef _max_independent(self, F) - cpdef _rank(self, F) - cpdef _circuit(self, F) - cpdef _fundamental_circuit(self, B, e) - cpdef _closure(self, F) + cpdef frozenset _max_independent(self, frozenset F) + cpdef int _rank(self, frozenset F) + cpdef frozenset _circuit(self, frozenset F) + cpdef frozenset _fundamental_circuit(self, frozenset B, e) + cpdef frozenset _closure(self, frozenset F) - cpdef _max_coindependent(self, F) - cpdef _corank(self, F) - cpdef _cocircuit(self, F) - cpdef _fundamental_cocircuit(self, B, e) - cpdef _coclosure(self, F) + cpdef frozenset _max_coindependent(self, frozenset F) + cpdef int _corank(self, frozenset F) + cpdef frozenset _cocircuit(self, frozenset F) + cpdef frozenset _fundamental_cocircuit(self, frozenset B, e) + cpdef frozenset _coclosure(self, frozenset F) - cpdef _augment(self, X, Y) - cpdef _is_independent(self, F) + cpdef frozenset _augment(self, frozenset X, frozenset Y) + cpdef bint _is_independent(self, frozenset F) - cpdef whitney_numbers2(self) + cpdef list whitney_numbers2(self) cdef _whitney_numbers2_rec(self, object f_vec, bitset_t* flats, bitset_t* todo, long elt, long rnk) - cpdef flats(self, R) cdef _flats_rec(self, SetSystem Rflats, long R, bitset_t* flats, bitset_t* todo, long elt, long rnk) - cpdef coflats(self, R) cdef _coflats_rec(self, SetSystem Rcoflats, long R, bitset_t* coflats, bitset_t* todo, long elt, long cornk) cdef _flat_element_inv(self, long k) cdef _flat_element_inv_rec(self, object f_inc, long R, bitset_t* flats, bitset_t* todo, long elt, long i) cpdef bases_count(self) - cpdef independent_r_sets(self, long r) - cpdef bases(self) - cpdef dependent_r_sets(self, long r) - cpdef nonbases(self) + cpdef SetSystem independent_sets(self, long k=*) + cpdef SetSystem dependent_sets(self, long k) - cpdef nonspanning_circuits(self) - cpdef cocircuits(self) - cpdef circuits(self) + cpdef SetSystem nonspanning_circuits(self) + cpdef SetSystem cocircuits(self) + cpdef SetSystem circuits(self, k=*) cpdef _characteristic_setsystem(self) cpdef _weak_invariant(self) @@ -95,6 +90,6 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _is_isomorphism(self, other, morphism) cdef bint __is_isomorphism(self, BasisExchangeMatroid other, morphism) noexcept - cpdef is_valid(self) + cpdef bint is_valid(self) cdef bint nxksrd(bitset_s *b, long n, long k, bint succ) noexcept diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 1fe648dc7d9..2e57bb00fdc 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -13,21 +13,8 @@ class :mod:`Matroid `. AUTHORS: - Rudi Pendavingh, Stefan van Zwam (2013-04-01): initial version - -TESTS:: - - sage: from sage.matroids.advanced import * - sage: import sage.matroids.basis_exchange_matroid - sage: M = sage.matroids.basis_exchange_matroid.BasisExchangeMatroid( - ....: groundset=[1, 2, 3], rank=2) - sage: TestSuite(M).run(skip="_test_pickling") - -Note that this is an abstract base class, without data structure, so no -pickling mechanism was implemented. - -Methods -======= """ + # **************************************************************************** # Copyright (C) 2013 Rudi Pendavingh # Copyright (C) 2013 Stefan van Zwam @@ -40,7 +27,6 @@ Methods from sage.matroids.matroid cimport Matroid from sage.matroids.set_system cimport SetSystem - from sage.data_structures.bitset_base cimport * cdef class BasisExchangeMatroid(Matroid): @@ -116,7 +102,7 @@ cdef class BasisExchangeMatroid(Matroid): All but the first of the above matroids are algebraic, and all implementations specializations of the algebraic one. - BasisExchangeMatroid internally renders subsets of the ground set as + BasisExchangeMatroid internally renders subsets of the groundset as bitsets. It provides optimized methods for enumerating bases, nonbases, flats, circuits, etc. """ @@ -132,9 +118,9 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``groundset`` -- a set. - - ``basis`` -- (default: ``None``) a subset of groundset. - - ``rank`` -- (default: ``None``) an integer. + - ``groundset`` -- set + - ``basis`` -- subset of groundset (default: ``None``) + - ``rank`` -- integer (default: ``None``) This initializer sets up a correspondence between elements of ``groundset`` and ``range(len(groundset))``. ``BasisExchangeMatroid`` @@ -154,6 +140,18 @@ cdef class BasisExchangeMatroid(Matroid): ['a', 'b', 'c', 'd', 'e', 'f'] sage: sorted(M.basis()) ['a', 'b', 'c'] + + + TESTS:: + + sage: from sage.matroids.advanced import * + sage: M = BasisExchangeMatroid(groundset=[1, 2, 3], rank=2) + sage: TestSuite(M).run(skip="_test_pickling") + + .. NOTE:: + + This is an abstract base class, without a data structure, so no + pickling mechanism was implemented. """ self._groundset_size = len(groundset) self._bitset_size = max(self._groundset_size, 1) @@ -233,9 +231,10 @@ cdef class BasisExchangeMatroid(Matroid): self._heuristic_partition_var._relabel(mapping) # the engine + cdef _pack(self, bitset_t I, F): """ - Encode a subset F of the groundset into a bitpacked set of integers + Encode a subset F of the groundset into a bitpacked set of integers. """ bitset_clear(I) for f in F: @@ -256,21 +255,22 @@ cdef class BasisExchangeMatroid(Matroid): # this method needs to be overridden by child class cdef bint _is_exchange_pair(self, long x, long y) except -1: """ - Test if current_basis-x + y is a basis + Test if current_basis-x + y is a basis. """ raise NotImplementedError # if this method is overridden by a child class, the child class needs to call this method cdef int _exchange(self, long x, long y) except -1: """ - put current_basis <-- current_basis-x + y + Put ``current_basis <-- current_basis-x + y``. """ bitset_discard(self._current_basis, x) bitset_add(self._current_basis, y) cdef int _move(self, bitset_t X, bitset_t Y) except -1: """ - Change current_basis to minimize intersection with ``X``, maximize intersection with ``Y``. + Change ``current_basis`` to minimize intersection with ``X``, maximize + intersection with ``Y``. """ cdef long x, y x = bitset_first(X) @@ -290,7 +290,8 @@ cdef class BasisExchangeMatroid(Matroid): cdef __fundamental_cocircuit(self, bitset_t C, long x): """ - Return the unique cocircuit that meets ``self._current_basis`` in exactly element ``x``. + Return the unique cocircuit that meets ``self._current_basis`` in + exactly element ``x``. """ cdef long y bitset_clear(C) @@ -452,9 +453,10 @@ cdef class BasisExchangeMatroid(Matroid): self._move(self._inside, self._outside) # functions for derived classes and for parent class + cdef bint _set_current_basis(self, F) noexcept: """ - Set _current_basis to subset of the groundset ``F``. + Set ``_current_basis`` to subset of the groundset ``F``. """ self._pack(self._input, F) bitset_difference(self._inside, self._current_basis, self._input) @@ -463,15 +465,14 @@ cdef class BasisExchangeMatroid(Matroid): return bitset_isempty(self._outside) and bitset_isempty(self._inside) # groundset and full_rank - cpdef groundset(self): + + cpdef frozenset groundset(self): """ Return the groundset of the matroid. The groundset is the set of elements that comprise the matroid. - OUTPUT: - - A set. + OUTPUT: set EXAMPLES:: @@ -481,15 +482,13 @@ cdef class BasisExchangeMatroid(Matroid): """ return self._groundset - cpdef groundset_list(self): + cpdef list groundset_list(self): """ Return a list of elements of the groundset of the matroid. The order of the list does not change between calls. - OUTPUT: - - A list. + OUTPUT: list .. SEEALSO:: @@ -533,9 +532,7 @@ cdef class BasisExchangeMatroid(Matroid): The *rank* of the matroid is the size of the largest independent subset of the groundset. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -554,9 +551,7 @@ cdef class BasisExchangeMatroid(Matroid): The *corank* of the matroid equals the rank of the dual matroid. It is given by ``M.size() - M.full_rank()``. - OUTPUT: - - Integer. + OUTPUT: integer .. SEEALSO:: @@ -587,9 +582,7 @@ cdef class BasisExchangeMatroid(Matroid): the internal state of the matroid. This state is updated by lots of methods, including the method ``M._move_current_basis()``. - OUTPUT: - - Set of elements. + OUTPUT: set of elements EXAMPLES:: @@ -611,13 +604,11 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - ``X`` -- an object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + a subset of ``self.groundset()`` - ``Y`` -- an object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + a subset of ``self.groundset()`` - OUTPUT: - - Nothing. + OUTPUT: nothing EXAMPLES:: @@ -633,89 +624,83 @@ cdef class BasisExchangeMatroid(Matroid): self._pack(self._input2, Y) self.__move_current_basis(self._input, self._input2) - cpdef _max_independent(self, F): + cpdef frozenset _max_independent(self, frozenset F): """ Compute a maximal independent subset. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - A subset of ``F``. + OUTPUT: subset of ``F`` EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: sorted(M._max_independent(set(['a', 'c', 'd', 'e', 'f']))) + sage: sorted(M._max_independent(frozenset(['a', 'c', 'd', 'e', 'f']))) ['a', 'c', 'd', 'e'] .. NOTE:: This is an unguarded method. For the version that verifies if - the input is indeed a subset of the ground set, + the input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__max_independent(self._output, self._input) return self.__unpack(self._output) - cpdef _rank(self, F): + cpdef int _rank(self, frozenset F): """ - Compute the rank of a subset of the ground set. + Compute the rank of a subset of the groundset. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: M._rank(set(['a', 'c', 'd', 'e', 'f'])) + sage: M._rank(frozenset(['a', 'c', 'd', 'e', 'f'])) 4 .. NOTE:: This is an unguarded method. For the version that verifies if - the input is indeed a subset of the ground set, + the input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__max_independent(self._output, self._input) return bitset_len(self._output) - cpdef _circuit(self, F): + cpdef frozenset _circuit(self, frozenset F): """ Return a minimal dependent subset. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - A circuit contained in ``F``, if it exists. Otherwise an error is - raised. + OUTPUT: circuit contained in ``F``, if it exists; otherwise, an error + is raised EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) sage: sorted(sage.matroids.matroid.Matroid._circuit(M, - ....: set(['a', 'c', 'd', 'e', 'f']))) + ....: frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] sage: sorted(sage.matroids.matroid.Matroid._circuit(M, - ....: set(['a', 'c', 'd']))) + ....: frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no circuit in independent set. @@ -723,14 +708,14 @@ cdef class BasisExchangeMatroid(Matroid): .. NOTE:: This is an unguarded method. For the version that verifies if - the input is indeed a subset of the ground set, + the input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__circuit(self._output, self._input) return self.__unpack(self._output) - cpdef _fundamental_circuit(self, B, e): + cpdef frozenset _fundamental_circuit(self, frozenset B, e): r""" Return the `B`-fundamental circuit using `e`. @@ -738,17 +723,15 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``B`` -- a basis of the matroid. - - ``e`` -- an element not in ``B``. + - ``B`` -- a basis of the matroid + - ``e`` -- an element not in ``B`` - OUTPUT: - - A set of elements. + OUTPUT: set of elements EXAMPLES:: sage: M = matroids.catalog.P8() - sage: sorted(M._fundamental_circuit('abcd', 'e')) + sage: sorted(M._fundamental_circuit(frozenset('abcd'), 'e')) ['a', 'b', 'c', 'e'] """ self._pack(self._input, B) @@ -757,119 +740,111 @@ cdef class BasisExchangeMatroid(Matroid): self.__fundamental_circuit(self._output, self._idx[e]) return self.__unpack(self._output) - cpdef _closure(self, F): + cpdef frozenset _closure(self, frozenset F): """ Return the closure of a set. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - The smallest closed set containing ``F``. + OUTPUT: the smallest closed set containing ``F`` EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: sorted(M._closure(set(['a', 'b', 'c']))) + sage: sorted(M._closure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] .. NOTE:: This is an unguarded method. For the version that verifies if the - input is indeed a subset of the ground set, see + input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__closure(self._output, self._input) return self.__unpack(self._output) - cpdef _max_coindependent(self, F): + cpdef frozenset _max_coindependent(self, frozenset F): """ Compute a maximal coindependent subset. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - OUTPUT: - - A maximal coindependent subset of ``F``. + OUTPUT: a maximal coindependent subset of ``F`` EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: sorted(M._max_coindependent(set(['a', 'c', 'd', 'e', 'f']))) + sage: sorted(M._max_coindependent(frozenset(['a', 'c', 'd', 'e', 'f']))) ['a', 'c', 'd', 'f'] .. NOTE:: This is an unguarded method. For the version that verifies if the - input is indeed a subset of the ground set, + input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__max_coindependent(self._output, self._input) return self.__unpack(self._output) - cpdef _corank(self, F): + cpdef int _corank(self, frozenset F): """ Return the corank of a set. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - Integer, the corank of ``F``. + OUTPUT: integer; the corank of ``F`` EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: M._corank(set(['a', 'e', 'g', 'd', 'h'])) + sage: M._corank(frozenset(['a', 'e', 'g', 'd', 'h'])) 4 .. NOTE:: This is an unguarded method. For the version that verifies if the - input is indeed a subset of the ground set, + input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__max_coindependent(self._output, self._input) return bitset_len(self._output) - cpdef _cocircuit(self, F): + cpdef frozenset _cocircuit(self, frozenset F): """ Return a minimal codependent subset. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - OUTPUT: - - A cocircuit contained in ``F``, if it exists. Otherwise an error is - raised. + OUTPUT: a cocircuit contained in ``F``, if it exists; otherwise, an + error is raised EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) sage: sorted(sage.matroids.matroid.Matroid._cocircuit(M, - ....: set(['a', 'c', 'd', 'e', 'f']))) + ....: frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] sage: sorted(sage.matroids.matroid.Matroid._cocircuit(M, - ....: set(['a', 'c', 'd']))) + ....: frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no cocircuit in coindependent set. @@ -877,14 +852,14 @@ cdef class BasisExchangeMatroid(Matroid): .. NOTE:: This is an unguarded method. For the version that verifies if the - input is indeed a subset of the ground set, + input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self.__cocircuit(self._output, self._input) return self.__unpack(self._output) - cpdef _fundamental_cocircuit(self, B, e): + cpdef frozenset _fundamental_cocircuit(self, frozenset B, e): r""" Return the `B`-fundamental circuit using `e`. @@ -892,17 +867,15 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``B`` -- a basis of the matroid. - - ``e`` -- an element of ``B``. - - OUTPUT: + - ``B`` -- a basis of the matroid + - ``e`` -- an element of ``B`` - A set of elements. + OUTPUT: set of elements EXAMPLES:: sage: M = matroids.catalog.P8() - sage: sorted(M._fundamental_cocircuit('efgh', 'e')) + sage: sorted(M._fundamental_cocircuit(frozenset('efgh'), 'e')) ['b', 'c', 'd', 'e'] """ self._pack(self._input, B) @@ -911,37 +884,35 @@ cdef class BasisExchangeMatroid(Matroid): self.__fundamental_cocircuit(self._output, self._idx[e]) return self.__unpack(self._output) - cpdef _coclosure(self, F): + cpdef frozenset _coclosure(self, frozenset F): """ Return the coclosure of a set. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - The smallest coclosed set containing ``X``. + OUTPUT: the smallest coclosed set containing ``X`` EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: sorted(M._coclosure(set(['a', 'b', 'c']))) + sage: sorted(M._coclosure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] .. NOTE:: This is an unguarded method. For the version that verifies if the - input is indeed a subset of the ground set, + input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) self._coclosure_internal(self._output, self._input) return self.__unpack(self._output) - cpdef _augment(self, X, Y): + cpdef frozenset _augment(self, frozenset X, frozenset Y): r""" Return a maximal subset `I` of `Y` such that `r(X + I)=r(X) + r(I)`. @@ -950,20 +921,18 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - ``Y`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``, and disjoint from ``X``. - - OUTPUT: + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` + - ``Y`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()``, and disjoint from ``X`` - A subset `I` of ``Y`` such that `r(X + I)=r(X) + r(I)`. + OUTPUT: a subset `I` of ``Y`` such that `r(X + I)=r(X) + r(I)`. EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: sorted(M._augment(set(['a']), set(['e', 'f', 'g', 'h']))) + sage: sorted(M._augment(frozenset(['a']), frozenset(['e', 'f', 'g', 'h']))) ['e', 'f', 'g'] """ self._pack(self._input, X) @@ -971,32 +940,30 @@ cdef class BasisExchangeMatroid(Matroid): self.__augment(self._output, self._input, self._input2) return self.__unpack(self._output) - cpdef _is_independent(self, F): + cpdef bint _is_independent(self, frozenset F): """ Test if input is independent. INPUT: - - ``F`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``F`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - Boolean. + OUTPUT: boolean EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: M._is_independent(set(['a', 'b', 'c'])) + sage: M._is_independent(frozenset(['a', 'b', 'c'])) True - sage: M._is_independent(set(['a', 'b', 'c', 'd'])) + sage: M._is_independent(frozenset(['a', 'b', 'c', 'd'])) False .. NOTE:: This is an unguarded method. For the version that verifies if - the input is indeed a subset of the ground set, + the input is indeed a subset of the groundset, see :meth:``. """ self._pack(self._input, F) @@ -1013,9 +980,7 @@ cdef class BasisExchangeMatroid(Matroid): deleting the complement of that subset is :meth:`connected `. - OUTPUT: - - A list of subsets. + OUTPUT: list of subsets .. SEEALSO:: @@ -1106,12 +1071,10 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``S`` -- a subset of the ground set - - ``T`` -- a subset of the ground set disjoint from ``S`` + - ``S`` -- a subset of the groundset + - ``T`` -- a subset of the groundset disjoint from ``S`` - OUTPUT: - - A tuple ``(I, X)`` containing a frozenset ``I`` and a frozenset ``X``. + OUTPUT: tuple ``(I, X)`` of two frozensets ALGORITHM: @@ -1121,13 +1084,13 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: sage: M = matroids.catalog.BetsyRoss() - sage: S = set('ab') - sage: T = set('cd') + sage: S = frozenset('ab') + sage: T = frozenset('cd') sage: I, X = M._link(S, T) sage: M.connectivity(X) 2 - sage: J = M.groundset()-(S|T|I) - sage: N = (M/I).delete(J) + sage: J = M.groundset() - (S | T | I) + sage: N = (M / I).delete(J) sage: N.connectivity(S) 2 """ @@ -1235,7 +1198,7 @@ cdef class BasisExchangeMatroid(Matroid): # enumeration - cpdef whitney_numbers2(self): + cpdef list whitney_numbers2(self): r""" Return the Whitney numbers of the second kind of the matroid. @@ -1243,7 +1206,7 @@ cdef class BasisExchangeMatroid(Matroid): `(W_0, \ldots, W_r)`, where `W_i` is the number of flats of rank `i`, and `r` is the rank of the matroid. - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -1276,7 +1239,7 @@ cdef class BasisExchangeMatroid(Matroid): cdef _whitney_numbers2_rec(self, object f_vec, bitset_t* flats, bitset_t* todo, long elt, long i): """ - Recursion for the whitney_numbers2 method. + Recursion for the ``whitney_numbers2`` method. """ cdef long e f_vec[i] += 1 @@ -1292,7 +1255,7 @@ cdef class BasisExchangeMatroid(Matroid): self._whitney_numbers2_rec(f_vec, flats, todo, e + 1, i + 1) e = bitset_next(todo[i], e) - cpdef flats(self, r): + cpdef SetSystem flats(self, long k): """ Return the collection of flats of the matroid of specified rank. @@ -1300,11 +1263,9 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``r`` -- A natural number. - - OUTPUT: + - ``k`` -- integer - An iterable containing all flats of rank ``r``. + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -1324,14 +1285,14 @@ cdef class BasisExchangeMatroid(Matroid): """ cdef bitset_t *flats cdef bitset_t *todo - if r < 0 or r > self.full_rank(): + if k < 0 or k > self.full_rank(): return SetSystem(self._E) - if r == self.full_rank(): + if k == self.full_rank(): return SetSystem(self._E, subsets=[self.groundset()]) - flats = sig_malloc((r + 1) * sizeof(bitset_t)) - todo = sig_malloc((r + 1) * sizeof(bitset_t)) + flats = sig_malloc((k + 1) * sizeof(bitset_t)) + todo = sig_malloc((k + 1) * sizeof(bitset_t)) - for i in range(r + 1): + for i in range(k + 1): bitset_init(flats[i], self._bitset_size) bitset_init(todo[i], self._bitset_size) Rflats = SetSystem(self._E) @@ -1339,8 +1300,8 @@ cdef class BasisExchangeMatroid(Matroid): bitset_clear(todo[0]) self.__closure(flats[0], todo[0]) bitset_complement(todo[0], flats[0]) - self._flats_rec(Rflats, r, flats, todo, 0, 0) - for i in range(r + 1): + self._flats_rec(Rflats, k, flats, todo, 0, 0) + for i in range(k + 1): bitset_free(flats[i]) bitset_free(todo[i]) sig_free(flats) @@ -1367,7 +1328,7 @@ cdef class BasisExchangeMatroid(Matroid): self._flats_rec(Rflats, R, flats, todo, e + 1, i + 1) e = bitset_next(todo[i], e) - cpdef coflats(self, r): + cpdef SetSystem coflats(self, long k): """ Return the collection of coflats of the matroid of specified corank. @@ -1375,11 +1336,9 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``r`` -- A natural number. + - ``k`` -- integer - OUTPUT: - - An iterable containing all coflats of corank ``r``. + OUTPUT: iterable containing all coflats of corank `k` .. SEEALSO:: @@ -1399,14 +1358,14 @@ cdef class BasisExchangeMatroid(Matroid): """ cdef bitset_t *coflats cdef bitset_t *todo - if r < 0 or r > self.full_corank(): + if k < 0 or k > self.full_corank(): return SetSystem(self._E) - if r == self.full_corank(): + if k == self.full_corank(): return SetSystem(self._E, subsets=[self.groundset()]) - coflats = sig_malloc((r + 1) * sizeof(bitset_t)) - todo = sig_malloc((r + 1) * sizeof(bitset_t)) + coflats = sig_malloc((k + 1) * sizeof(bitset_t)) + todo = sig_malloc((k + 1) * sizeof(bitset_t)) - for i in range(r + 1): + for i in range(k + 1): bitset_init(coflats[i], self._bitset_size) bitset_init(todo[i], self._bitset_size) Rcoflats = SetSystem(self._E) @@ -1414,8 +1373,8 @@ cdef class BasisExchangeMatroid(Matroid): bitset_clear(todo[0]) self._coclosure_internal(coflats[0], todo[0]) bitset_complement(todo[0], coflats[0]) - self._coflats_rec(Rcoflats, r, coflats, todo, 0, 0) - for i in range(r + 1): + self._coflats_rec(Rcoflats, k, coflats, todo, 0, 0) + for i in range(k + 1): bitset_free(coflats[i]) bitset_free(todo[i]) sig_free(coflats) @@ -1514,9 +1473,7 @@ cdef class BasisExchangeMatroid(Matroid): :meth:`M.basis() `. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -1537,13 +1494,14 @@ cdef class BasisExchangeMatroid(Matroid): self._bcount = res return self._bcount - cpdef independent_sets(self): + cpdef SetSystem independent_sets(self, long k=-1): r""" - Return the list of independent subsets of the matroid. + Return the independent sets of the matroid. - OUTPUT: + INPUT: - An iterable containing all independent subsets of the matroid. + - ``k`` -- integer (optional); if specified, return the size-`k` + independent sets of the matroid EXAMPLES:: @@ -1551,176 +1509,123 @@ cdef class BasisExchangeMatroid(Matroid): sage: I = M.independent_sets() sage: len(I) 57 + sage: M = matroids.catalog.N1() + sage: M.bases_count() + 184 + sage: [len(M.independent_sets(k)) for k in range(M.full_rank() + 1)] + [1, 10, 45, 120, 201, 184] + + TESTS:: + + sage: len([B for B in M.bases()]) + 184 """ cdef bitset_t *I cdef bitset_t *T cdef long i, e, r - - res = SetSystem(self._E) - bitset_clear(self._input) - res._append(self._input) - if not self._E: + if k == -1: # all independent sets + res = SetSystem(self._E) + bitset_clear(self._input) + res._append(self._input) + if not self._E: + return res + + r = self.full_rank() + I = sig_malloc((r + 1) * sizeof(bitset_t)) + T = sig_malloc((r + 1) * sizeof(bitset_t)) + for i in range(r + 1): + bitset_init(I[i], self._bitset_size) + bitset_init(T[i], self._bitset_size) + + i = 0 + bitset_clear(I[0]) + bitset_copy(self._input, I[0]) + self.__closure(T[0], self._input) + while i >= 0: + e = bitset_first_in_complement(T[i]) + if e >= 0: + bitset_add(T[i], e) + bitset_copy(I[i+1], I[i]) + bitset_add(I[i+1], e) + res._append(I[i+1]) + bitset_copy(self._input, I[i+1]) + self.__closure(T[i+1], self._input) + bitset_union(T[i+1],T[i+1],T[i]) + i = i + 1 + else: + i = i - 1 + for i in range(r + 1): + bitset_free(I[i]) + bitset_free(T[i]) + sig_free(I) + sig_free(T) return res - r = self.full_rank() - I = sig_malloc((r + 1) * sizeof(bitset_t)) - T = sig_malloc((r + 1) * sizeof(bitset_t)) - for i in range(r + 1): - bitset_init(I[i], self._bitset_size) - bitset_init(T[i], self._bitset_size) - - i = 0 - bitset_clear(I[0]) - bitset_copy(self._input, I[0]) - self.__closure(T[0], self._input) - while i >= 0: - e = bitset_first_in_complement(T[i]) - if e >= 0: - bitset_add(T[i], e) - bitset_copy(I[i+1], I[i]) - bitset_add(I[i+1], e) - res._append(I[i+1]) - bitset_copy(self._input, I[i+1]) - self.__closure(T[i+1], self._input) - bitset_union(T[i+1],T[i+1],T[i]) - i = i + 1 - else: - i = i - 1 - for i in range(r + 1): - bitset_free(I[i]) - bitset_free(T[i]) - sig_free(I) - sig_free(T) - return res - - cpdef independent_r_sets(self, long r): - """ - Return the list of size-``r`` independent subsets of the matroid. - - INPUT: - - - ``r`` -- a nonnegative integer. - - OUTPUT: - - An iterable containing all independent subsets of the matroid of - cardinality ``r``. - - EXAMPLES:: - - sage: M = matroids.catalog.N1() - sage: M.bases_count() - 184 - sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] - [1, 10, 45, 120, 201, 184] - """ - cdef SetSystem BB - BB = SetSystem(self._E) - if r < 0 or r > self.full_rank(): + # independent k-sets + cdef SetSystem BB = SetSystem(self._E) + if k < 0 or k > self.full_rank(): return BB bitset_clear(self._input) - bitset_set_first_n(self._input, r) + bitset_set_first_n(self._input, k) repeat = True while repeat: if self.__is_independent(self._input): BB._append(self._input) - repeat = nxksrd(self._input, self._groundset_size, r, True) + repeat = nxksrd(self._input, self._groundset_size, k, True) return BB - cpdef bases(self): + cpdef SetSystem dependent_sets(self, long k): """ - Return the list of bases of the matroid. - - A *basis* is a maximal independent set. - - OUTPUT: - - An iterable containing all bases of the matroid. - - EXAMPLES:: - - sage: M = matroids.catalog.N1() - sage: M.bases_count() - 184 - sage: len([B for B in M.bases()]) - 184 - """ - return self.independent_r_sets(self.full_rank()) - - cpdef dependent_r_sets(self, long r): - """ - Return the list of dependent subsets of fixed size. + Return the dependent sets of fixed size. INPUT: - - ``r`` -- a nonnegative integer. + - ``k`` -- integer - OUTPUT: - - An iterable containing all dependent subsets of size ``r``. + OUTPUT: iterable containing all dependent sets of size ``k`` EXAMPLES:: sage: M = matroids.catalog.N1() sage: len(M.nonbases()) 68 - sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] + sage: [len(M.dependent_sets(k)) for k in range(M.full_rank() + 1)] [0, 0, 0, 0, 9, 68] + + TESTS:: + + sage: binomial(M.size(), M.full_rank())-M.bases_count() # needs sage.symbolic + 68 + sage: len([B for B in M.nonbases()]) + 68 """ cdef SetSystem NB NB = SetSystem(self._E) - if r < 0 or r > self.size(): + if k < 0 or k > self.size(): return NB bitset_clear(self._input) - bitset_set_first_n(self._input, r) + bitset_set_first_n(self._input, k) repeat = True - if r > self.full_rank(): + if k > self.full_rank(): while repeat: NB._append(self._input) - repeat = nxksrd(self._input, self._groundset_size, r, True) + repeat = nxksrd(self._input, self._groundset_size, k, True) else: while repeat: if not self.__is_independent(self._input): NB._append(self._input) - repeat = nxksrd(self._input, self._groundset_size, r, True) + repeat = nxksrd(self._input, self._groundset_size, k, True) NB.resize() return NB - cpdef nonbases(self): - """ - Return the list of nonbases of the matroid. - - A *nonbasis* is a set with cardinality ``self.full_rank()`` that is - not a basis. - - OUTPUT: - - An iterable containing the nonbases of the matroid. - - .. SEEALSO:: - - :meth:`Matroid.basis() ` - - EXAMPLES:: - - sage: M = matroids.catalog.N1() - sage: binomial(M.size(), M.full_rank())-M.bases_count() # needs sage.symbolic - 68 - sage: len([B for B in M.nonbases()]) - 68 - """ - return self.dependent_r_sets(self.full_rank()) - - cpdef nonspanning_circuits(self): + cpdef SetSystem nonspanning_circuits(self): """ - Return the list of nonspanning circuits of the matroid. + Return the nonspanning circuits of the matroid. A *nonspanning circuit* is a circuit whose rank is strictly smaller than the rank of the matroid. - OUTPUT: - - An iterable containing all nonspanning circuits. + OUTPUT: iterable containing all nonspanning circuits .. SEEALSO:: @@ -1760,16 +1665,14 @@ cdef class BasisExchangeMatroid(Matroid): NSC.resize() return NSC - cpdef noncospanning_cocircuits(self): + cpdef SetSystem noncospanning_cocircuits(self): """ - Return the list of noncospanning cocircuits of the matroid. + Return the noncospanning cocircuits of the matroid. A *noncospanning cocircuit* is a cocircuit whose corank is strictly smaller than the corank of the matroid. - OUTPUT: - - An iterable containing all nonspanning circuits. + OUTPUT: iterable containing all nonspanning circuits .. SEEALSO:: @@ -1810,13 +1713,11 @@ cdef class BasisExchangeMatroid(Matroid): NSC.resize() return NSC - cpdef cocircuits(self): + cpdef SetSystem cocircuits(self): """ - Return the list of cocircuits of the matroid. + Return the cocircuits of the matroid. - OUTPUT: - - An iterable containing all cocircuits. + OUTPUT: iterable containing all cocircuits .. SEEALSO:: @@ -1858,13 +1759,11 @@ cdef class BasisExchangeMatroid(Matroid): NSC.resize() return NSC - cpdef circuits(self): + cpdef SetSystem circuits(self, k=None): """ - Return the list of circuits of the matroid. - - OUTPUT: + Return the circuits of the matroid. - An iterable containing all circuits. + OUTPUT: iterable containing all circuits .. SEEALSO:: @@ -1906,18 +1805,19 @@ cdef class BasisExchangeMatroid(Matroid): f = bitset_next(self._input2, f + 1) repeat = nxksrd(self._input, self._groundset_size, self._matroid_rank, True) NSC.resize() - return NSC + if k: + return SetSystem(self.groundset(), [C for C in NSC if len(C) == k]) + else: + return NSC # isomorphism cpdef _characteristic_setsystem(self): r""" Return a characteristic set-system for this matroid, on the same - ground set. - - OUTPUT: + groundset. - A :class:`` instance. + OUTPUT: :class:`` EXAMPLES:: @@ -1936,14 +1836,12 @@ cdef class BasisExchangeMatroid(Matroid): """ Return an isomorphism invariant of the matroid. - Compared to BasisExchangeMatroid._strong_invariant() this invariant + Compared to ``BasisExchangeMatroid._strong_invariant()`` this invariant distinguishes less frequently between nonisomorphic matroids but takes less time to compute. See also :meth:``. - OUTPUT: - - An integer isomorphism invariant. + OUTPUT: integer isomorphism invariant EXAMPLES:: @@ -1982,14 +1880,12 @@ cdef class BasisExchangeMatroid(Matroid): """ Return an isomorphism invariant of the matroid. - Compared to BasisExchangeMatroid._weak_invariant() this invariant + Compared to ``BasisExchangeMatroid._weak_invariant()`` this invariant distinguishes more frequently between nonisomorphic matroids but takes more time to compute. See also :meth:``. - OUTPUT: - - An integer isomorphism invariant. + OUTPUT: integer isomorphism invariant EXAMPLES:: @@ -2006,7 +1902,7 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _strong_partition(self): """ - Return an equitable partition which refines _weak_partition(). + Return an equitable partition which refines ``_weak_partition()``. EXAMPLES:: @@ -2021,7 +1917,7 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _heuristic_invariant(self): """ Return a number characteristic for the construction of - _heuristic_partition(). + ``_heuristic_partition()``. EXAMPLES:: @@ -2044,7 +1940,7 @@ cdef class BasisExchangeMatroid(Matroid): The purpose of this partition is to heuristically find an isomorphism between two matroids, by lining up their respective - heuristic_partitions. + ``heuristic_partitions``. EXAMPLES:: @@ -2073,17 +1969,15 @@ cdef class BasisExchangeMatroid(Matroid): """ Return the equitable refinement of a given ordered partition. - The coarsest equitable partition of the ground set of this matroid + The coarsest equitable partition of the groundset of this matroid that refines P. INPUT: - - ``P`` -- (default: ``None``) an ordered partition of the groundset. - If ``None``, the trivial partition is used. + - ``P`` -- ordered partition of the groundset (default: ``None``); + if ``None``, the trivial partition is used - OUTPUT: - - A SetSystem. + OUTPUT: SetSystem EXAMPLES:: @@ -2102,17 +1996,15 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _is_isomorphism(self, other, morphism): r""" - Version of is_isomorphism() that does no type checking. + Version of ``is_isomorphism()`` that does no type checking. INPUT: - - ``other`` -- A matroid instance. + - ``other`` -- matroid - ``morphism`` -- a dictionary mapping the groundset of ``self`` to the groundset of ``other`` - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -2175,11 +2067,9 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid - OUTPUT: - - A dictionary, or ``None`` + OUTPUT: dictionary or ``None`` EXAMPLES:: @@ -2263,13 +2153,11 @@ cdef class BasisExchangeMatroid(Matroid): INPUT: - - ``other`` -- A matroid, - - optional parameter ``certificate`` -- Boolean. - - OUTPUT: + - ``other`` -- matroid + - ``certificate`` -- boolean (default: ``False``) - Boolean, - and, if certificate = True, a dictionary giving the isomorphism or None + OUTPUT: boolean, and, if ``certificate = True``, a dictionary giving + the isomorphism or ``None`` .. NOTE:: @@ -2341,7 +2229,7 @@ cdef class BasisExchangeMatroid(Matroid): return self._characteristic_setsystem()._isomorphism(other._characteristic_setsystem(), PS, PO) is not None - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data obey the matroid axioms. @@ -2352,9 +2240,7 @@ cdef class BasisExchangeMatroid(Matroid): * if `X` and `Y` are in `B`, and `x` is in `X - Y`, then there is a `y` in `Y - X` such that `(X - x) + y` is again a member of `B`. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -2410,7 +2296,6 @@ cdef class BasisExchangeMatroid(Matroid): pointerX += 1 return True - cdef bint nxksrd(bitset_s* b, long n, long k, bint succ) noexcept: """ Next size-k subset of a size-n set in a revolving-door sequence. diff --git a/src/sage/matroids/basis_matroid.pxd b/src/sage/matroids/basis_matroid.pxd index 98400ba26ca..5789ad98937 100644 --- a/src/sage/matroids/basis_matroid.pxd +++ b/src/sage/matroids/basis_matroid.pxd @@ -1,5 +1,4 @@ from sage.data_structures.bitset cimport bitset_t -from sage.matroids.matroid cimport Matroid from sage.matroids.basis_exchange_matroid cimport BasisExchangeMatroid from sage.matroids.set_system cimport SetSystem @@ -16,11 +15,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): cdef reset_current_basis(self) - cpdef _is_basis(self, X) + cpdef bint _is_basis(self, frozenset X) cpdef bases_count(self) - cpdef bases(self) - cpdef nonbases(self) + cpdef SetSystem bases(self) + cpdef SetSystem nonbases(self) cpdef truncation(self) cpdef _extension(self, e, H) @@ -40,7 +39,6 @@ cdef class BasisMatroid(BasisExchangeMatroid): cpdef _isomorphism(self, other) cpdef _is_isomorphic(self, other, certificate=*) - cdef binom_init(long n, long k) cdef long set_to_index(bitset_t S) noexcept cdef index_to_set(bitset_t, long, long, long) diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index 6ff808d710f..5ae38178df6 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -52,16 +52,8 @@ testing matroid isomorphism and minor inclusion. AUTHORS: - Rudi Pendavingh, Stefan van Zwam (2013-04-01): initial version - -TESTS:: - - sage: F = matroids.catalog.Fano() - sage: M = Matroid(bases=F.bases()) - sage: TestSuite(M).run() - -Methods -======= """ + # **************************************************************************** # Copyright (C) 2013 Rudi Pendavingh # Copyright (C) 2013 Stefan van Zwam @@ -72,30 +64,29 @@ Methods # https://www.gnu.org/licenses/ # **************************************************************************** +from cpython.object cimport Py_EQ, Py_NE +from itertools import combinations from sage.data_structures.bitset_base cimport * +from sage.misc.decorators import rename_keyword from sage.structure.richcmp cimport rich_to_bool from sage.matroids.matroid cimport Matroid from sage.matroids.basis_exchange_matroid cimport BasisExchangeMatroid from sage.matroids.set_system cimport SetSystem from sage.matroids.utilities import cmp_elements_key -from cpython.object cimport Py_EQ, Py_NE -from sage.misc.decorators import rename_keyword -from itertools import combinations # class of general matroids, represented by their list of bases - cdef class BasisMatroid(BasisExchangeMatroid): """ Create general matroid, stored as a set of bases. INPUT: - - ``M`` (optional) -- a matroid. - - ``groundset`` (optional) -- any iterable set. - - ``bases`` (optional) -- a set of subsets of ``groundset``. - - ``nonbases`` (optional) -- a set of subsets of ``groundset``. - - ``rank`` (optional) -- a natural number + - ``M`` -- matroid (optional) + - ``groundset`` -- any iterable set (optional) + - ``bases`` -- set of subsets of the ``groundset`` (optional) + - ``nonbases`` -- set of subsets of the ``groundset`` (optional) + - ``rank`` -- natural number (optional) EXAMPLES: @@ -157,6 +148,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): True sage: len(set(F.bases()).difference(M.bases())) 0 + + TESTS:: + + sage: F = matroids.catalog.Fano() + sage: M = Matroid(bases=F.bases()) + sage: TestSuite(M).run() """ cdef SetSystem NB cdef long i @@ -216,12 +213,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): if bases is not None: if len(bases) == 0: - raise ValueError("set of bases must be nonempty.") + raise ValueError("set of bases must be nonempty") self._bcount = 0 for B in bases: b = frozenset(B) if len(b) != self._matroid_rank: - raise ValueError("basis has wrong cardinality.") + raise ValueError("basis has wrong cardinality") if not b.issubset(self._groundset): raise ValueError("basis is not a subset of the groundset") self._pack(self._b, b) @@ -276,8 +273,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``x`` -- an integer - - ``y`` -- an integer + - ``x`` -- integer + - ``y`` -- integer OUTPUT: @@ -302,14 +299,14 @@ cdef class BasisMatroid(BasisExchangeMatroid): # a function that is very efficient for this class - cpdef _is_basis(self, X): + cpdef bint _is_basis(self, frozenset X): """ Test if input is a basis. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` .. WARNING:: @@ -317,16 +314,14 @@ cdef class BasisMatroid(BasisExchangeMatroid): i.e. ``len(X) == self.full_rank()``. Otherwise its behavior is undefined. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: sage: M = Matroid(bases=matroids.catalog.Vamos().bases()) - sage: M._is_basis(set(['a', 'b', 'c', 'e'])) + sage: M._is_basis(frozenset(['a', 'b', 'c', 'e'])) True - sage: M._is_basis(set(['a', 'b', 'c', 'd'])) + sage: M._is_basis(frozenset(['a', 'b', 'c', 'd'])) False """ self._pack(self._b, X) @@ -338,14 +333,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): r""" Return the dual of the matroid. - Let `M` be a matroid with ground set `E`. If `B` is the set of bases + Let `M` be a matroid with groundset `E`. If `B` is the set of bases of `M`, then the set `\{E - b : b \in B\}` is the set of bases of another matroid, the *dual* of `M`. - OUTPUT: - - The dual matroid. - EXAMPLES:: sage: M = Matroid(bases=matroids.catalog.Pappus().bases()) @@ -380,10 +371,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` .. NOTE:: @@ -394,15 +385,13 @@ cdef class BasisMatroid(BasisExchangeMatroid): - ``deletions`` is coindependent - ``contractions`` and ``deletions`` are disjoint. - OUTPUT: - - A matroid. + OUTPUT: matroid EXAMPLES:: sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.catalog.Vamos()) - sage: M._minor(contractions=set(['a']), deletions=set(['b', 'c'])) + sage: M._minor(contractions=frozenset(['a']), deletions=frozenset(['b', 'c'])) Matroid of rank 3 on 5 elements with 10 bases """ E = self.groundset() - (contractions | deletions) @@ -419,9 +408,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): can be obtained by adding an element freely to the span of the matroid and then contracting that element. - OUTPUT: - - A matroid. + OUTPUT: matroid .. SEEALSO:: @@ -440,7 +427,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): """ if self.full_rank() == 0: return None - return BasisMatroid(groundset=self._E, nonbases=self.dependent_r_sets(self.full_rank() - 1), rank=self.full_rank() - 1) + return BasisMatroid(groundset=self._E, nonbases=self.dependent_sets(self.full_rank() - 1), rank=self.full_rank() - 1) cpdef _extension(self, e, H): r""" @@ -452,13 +439,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``element`` -- a hashable object not in ``self.groundset()``. - - ``hyperplanes`` -- the set of hyperplanes of a linear subclass of - ``self``. + - ``element`` -- a hashable object not in ``self.groundset()`` + - ``hyperplanes`` -- the set of hyperplanes of a linear subclass of ``self`` - OUTPUT: - - A matroid. + OUTPUT: matroid EXAMPLES:: @@ -480,7 +464,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): return BasisMatroid(groundset=self._E + (e,), bases=[set()]) BB = self.bases() - BT = self.independent_r_sets(self.full_rank() - 1) + BT = self.independent_sets(self.full_rank() - 1) se = set([e]) BE = [] for B in BT: @@ -501,12 +485,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``e`` -- the label of the new element. Assumed to be outside the - current groundset. + - ``e`` -- the label of the new element; assumed to be outside the + current groundset - OUTPUT: - - The extension of this matroid by a coloop. + OUTPUT: the extension of this matroid by a coloop EXAMPLES:: @@ -570,9 +552,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): r""" Return the number of bases of the matroid. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -586,15 +566,13 @@ cdef class BasisMatroid(BasisExchangeMatroid): self._bcount = bitset_len(self._bb) return self._bcount - cpdef bases(self): + cpdef SetSystem bases(self): r""" - Return the list of bases of the matroid. + Return the bases of the matroid. A *basis* is a maximal independent set. - OUTPUT: - - An iterable containing all bases of the matroid. + OUTPUT: iterable containing all bases of the matroid EXAMPLES:: @@ -617,16 +595,14 @@ cdef class BasisMatroid(BasisExchangeMatroid): b = bitset_next(self._bb, b + 1) return BB - cpdef nonbases(self): + cpdef SetSystem nonbases(self): r""" - Return the list of nonbases of the matroid. + Return the nonbases of the matroid. A *nonbasis* is a set with cardinality ``self.full_rank()`` that is not a basis. - OUTPUT: - - An iterable containing the nonbases of the matroid. + OUTPUT: iterable containing the nonbases of the matroid .. SEEALSO:: @@ -667,13 +643,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): Return an isomorphism invariant based on the incidences of groundset elements with bases. - INPUT: - - - Nothing - - OUTPUT: - - An integer. + OUTPUT: integer EXAMPLES:: @@ -725,14 +695,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): """ Return an isomorphism invariant of the matroid. - Compared to BasisMatroid._bases_invariant() this invariant + Compared to ``BasisMatroid._bases_invariant()`` this invariant distinguishes more frequently between nonisomorphic matroids but takes more time to compute. See also :meth:``. - OUTPUT: - - an integer isomorphism invariant. + OUTPUT: integer isomorphism invariant EXAMPLES:: @@ -833,11 +801,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``e`` -- an element of the ground set - - OUTPUT: + - ``e`` -- element of the groundset - Boolean. + OUTPUT: boolean .. SEEALSO:: @@ -879,15 +845,13 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- a BasisMatroid - - ``morphism`` -- a dictionary with sends each element of the + - ``other`` -- BasisMatroid + - ``morphism`` -- dictionary with sends each element of the groundset of this matroid to a distinct element of the groundset of ``other`` - OUTPUT: - - ``True`` if ``morphism[self]`` is a relaxation of ``other``; - ``False`` otherwise. + OUTPUT: ``True`` if ``morphism[self]`` is a relaxation of ``other``; + ``False`` otherwise EXAMPLES:: @@ -935,13 +899,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A matroid instance. - - ``morphism`` -- a dictionary mapping the groundset of ``self`` to - the groundset of ``other``. - - OUTPUT: + - ``other`` -- matroid + - ``morphism`` -- dictionary mapping the groundset of ``self`` to + the groundset of ``other`` - Boolean. + OUTPUT: boolean .. SEEALSO:: @@ -970,11 +932,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- a matroid. + - ``other`` -- matroid - OUTPUT: - - A dictionary, or ``None`` + OUTPUT: dictionary or ``None`` .. NOTE:: @@ -1049,13 +1009,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A matroid, - - optional parameter ``certificate`` -- Boolean. - - OUTPUT: + - ``other`` -- matroid + - ``certificate`` -- boolean (default: ``False``) - Boolean, - and, if certificate = True, a dictionary giving the isomorphism or None + OUTPUT: boolean, and, if ``certificate = True``, a dictionary giving + the isomorphism or ``None`` .. NOTE:: @@ -1202,10 +1160,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): version = 0 return sage.matroids.unpickling.unpickle_basis_matroid, (version, data) - cdef long binom[2956][33] # Cached binomial table - cdef binom_init(long N, long K): """ Fill up the cached binomial table. @@ -1247,10 +1203,9 @@ cdef long set_to_index(bitset_t S) noexcept: s = bitset_next(S, s + 1) return index - cdef index_to_set(bitset_t S, long index, long k, long n): r""" - Compute the k-subset of `\{0, ..., n-1\}` of rank index + Compute the k-subset of `\{0, ..., n-1\}` of rank index. """ bitset_clear(S) cdef long s = n diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index 55dd69d2ef4..e5b5c065fac 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -4,8 +4,8 @@ This module imports the individual matroids accessible through :mod:`matroids.catalog ` (type this and hit :kbd:`Tab` for a list). - """ + from sage.matroids.database_matroids import ( U24, U25, U35, K4, Whirl3, Q6, P6, U36, R6, Fano, FanoDual, NonFano, NonFanoDual, O7, P7, @@ -16,6 +16,7 @@ R12, ExtendedTernaryGolayCode, T12, PG23, ) + from sage.matroids.database_matroids import ( RelaxedNonFano, TippedFree3spike, AG23minusDY, TQ8, P8p, KP8, Sp8, Sp8pp, LP8, WQ8, @@ -30,6 +31,7 @@ FA15, N4, ) + from sage.matroids.database_matroids import ( NonVamos, NotP8, AG23minus, P9, R9A, R9B, Block_9_4, TicTacToe, diff --git a/src/sage/matroids/circuit_closures_matroid.pxd b/src/sage/matroids/circuit_closures_matroid.pxd index 4c6ef771057..878443d86f3 100644 --- a/src/sage/matroids/circuit_closures_matroid.pxd +++ b/src/sage/matroids/circuit_closures_matroid.pxd @@ -1,16 +1,15 @@ from sage.matroids.matroid cimport Matroid - cdef class CircuitClosuresMatroid(Matroid): cdef frozenset _groundset # _E cdef dict _circuit_closures # _CC cdef int _matroid_rank # _R - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) cpdef full_rank(self) - cpdef _is_independent(self, F) - cpdef _max_independent(self, F) - cpdef _circuit(self, F) - cpdef circuit_closures(self) + cpdef bint _is_independent(self, frozenset F) + cpdef frozenset _max_independent(self, frozenset F) + cpdef frozenset _circuit(self, frozenset F) + cpdef dict circuit_closures(self) cpdef _is_isomorphic(self, other, certificate=*) cpdef relabel(self, mapping) diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index e26c502c7f5..4d45022484b 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -47,6 +47,7 @@ AUTHORS: - Rudi Pendavingh, Stefan van Zwam (2013-04-01): initial version """ + # **************************************************************************** # Copyright (C) 2013 Rudi Pendavingh # Copyright (C) 2013 Stefan van Zwam @@ -57,12 +58,11 @@ AUTHORS: # https://www.gnu.org/licenses/ # **************************************************************************** +from cpython.object cimport Py_EQ, Py_NE from sage.structure.richcmp cimport rich_to_bool, richcmp from sage.matroids.matroid cimport Matroid from sage.matroids.set_system cimport SetSystem -from sage.matroids.utilities import setprint_s -from cpython.object cimport Py_EQ, Py_NE - +from sage.matroids.utilities import setprint_s, cmp_elements_key cdef class CircuitClosuresMatroid(Matroid): r""" @@ -78,7 +78,7 @@ cdef class CircuitClosuresMatroid(Matroid): to store, giving an upper bound of `O(2^n)` on the space complexity of the entire matroid. - A subset `X` of the ground set is independent if and only if + A subset `X` of the groundset is independent if and only if `| X \cap ` closure `(C) | \leq k` for all circuits `C` of `M` with `r(C)=k`. @@ -88,11 +88,11 @@ cdef class CircuitClosuresMatroid(Matroid): INPUT: - - ``M`` -- (default: ``None``) an arbitrary matroid. - - ``groundset`` -- (default: ``None``) the groundset of a matroid. - - ``circuit_closures`` -- (default: ``None``) the collection of circuit - closures of a matroid, presented as a dictionary whose keys are ranks, - and whose values are sets of circuit closures of the specified rank. + - ``M`` -- matroid (default: ``None``) + - ``groundset`` -- groundset of a matroid (default: ``None``) + - ``circuit_closures`` -- dict (default: ``None``); the collection of + circuit closures of a matroid presented as a dictionary whose keys are + ranks, and whose values are sets of circuit closures of the specified rank OUTPUT: @@ -122,7 +122,7 @@ cdef class CircuitClosuresMatroid(Matroid): True """ - # necessary + # necessary (__init__, groundset, _rank) def __init__(self, M=None, groundset=None, circuit_closures=None): """ @@ -163,15 +163,13 @@ cdef class CircuitClosuresMatroid(Matroid): self._circuit_closures[k] = frozenset([frozenset(X) for X in circuit_closures[k]]) self._matroid_rank = self.rank(self._groundset) - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. The groundset is the set of elements that comprise the matroid. - OUTPUT: - - A set. + OUTPUT: frozenset EXAMPLES:: @@ -181,7 +179,7 @@ cdef class CircuitClosuresMatroid(Matroid): """ return frozenset(self._groundset) - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): """ Return the rank of a set ``X``. @@ -190,16 +188,14 @@ cdef class CircuitClosuresMatroid(Matroid): INPUT: - - ``X`` -- an object with Python's ``frozenset`` interface. - - OUTPUT: + - ``X`` -- an object with Python's ``frozenset`` interface - The rank of ``X`` in the matroid. + OUTPUT: the rank of ``X`` in the matroid EXAMPLES:: sage: M = matroids.catalog.NonPappus() - sage: M._rank('abc') + sage: M._rank(frozenset('abc')) 2 """ return len(self._max_independent(X)) @@ -213,9 +209,7 @@ cdef class CircuitClosuresMatroid(Matroid): The *rank* of the matroid is the size of the largest independent subset of the groundset. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -227,25 +221,23 @@ cdef class CircuitClosuresMatroid(Matroid): """ return self._matroid_rank - cpdef _is_independent(self, F): + cpdef bint _is_independent(self, frozenset F): """ Test if input is independent. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_independent(set(['a', 'b', 'c'])) + sage: M._is_independent(frozenset(['a', 'b', 'c'])) True - sage: M._is_independent(set(['a', 'b', 'c', 'd'])) + sage: M._is_independent(frozenset(['a', 'b', 'c', 'd'])) False """ for r in sorted(self._circuit_closures): @@ -257,23 +249,21 @@ cdef class CircuitClosuresMatroid(Matroid): return False return True - cpdef _max_independent(self, F): + cpdef frozenset _max_independent(self, frozenset F): """ Compute a maximal independent subset. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - OUTPUT: - - A maximal independent subset of ``X``. + OUTPUT: a maximal independent subset of ``X`` EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: X = M._max_independent(set(['a', 'c', 'd', 'e', 'f'])) + sage: X = M._max_independent(frozenset(['a', 'c', 'd', 'e', 'f'])) sage: sorted(X) # random ['a', 'd', 'e', 'f'] sage: M.is_independent(X) @@ -294,26 +284,24 @@ cdef class CircuitClosuresMatroid(Matroid): return frozenset(I) - cpdef _circuit(self, F): + cpdef frozenset _circuit(self, frozenset F): """ Return a minimal dependent subset. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - OUTPUT: + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - A circuit contained in ``X``, if it exists. Otherwise an error is - raised. + OUTPUT: a circuit contained in ``X``, if it exists; otherwise, an error + is raised EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: sorted(M._circuit(set(['a', 'c', 'd', 'e', 'f']))) + sage: sorted(M._circuit(frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] - sage: sorted(M._circuit(set(['a', 'c', 'd']))) + sage: sorted(M._circuit(frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no circuit in independent set @@ -327,16 +315,14 @@ cdef class CircuitClosuresMatroid(Matroid): return frozenset(S) raise ValueError("no circuit in independent set") - cpdef circuit_closures(self): + cpdef dict circuit_closures(self): """ - Return the list of closures of circuits of the matroid. + Return the closures of circuits of the matroid. A *circuit closure* is a closed set containing a circuit. - OUTPUT: - - A dictionary containing the circuit closures of the matroid, indexed - by their ranks. + OUTPUT: dictionary containing the circuit closures of the matroid, + indexed by their ranks .. SEEALSO:: @@ -369,13 +355,11 @@ cdef class CircuitClosuresMatroid(Matroid): INPUT: - - ``other`` -- A matroid, - - optional parameter ``certificate`` -- Boolean. - - OUTPUT: + - ``other`` -- matroid + - ``certificate`` -- boolean (default: ``False``) - Boolean, - and, if certificate = True, a dictionary giving the isomorphism or None + OUTPUT: boolean, and, if ``certificate = True``, a dictionary giving + the isomorphism or ``None`` .. NOTE:: @@ -464,8 +448,8 @@ cdef class CircuitClosuresMatroid(Matroid): We take a very restricted view on equality: the objects need to be of the exact same type (so no subclassing) and the internal data need to - be the same. For BasisMatroids, this means that the groundsets and the - sets of bases of the two matroids are equal. + be the same. For ``BasisMatroid``s, this means that the groundsets and + the sets of bases of the two matroids are equal. EXAMPLES:: diff --git a/src/sage/matroids/circuits_matroid.pxd b/src/sage/matroids/circuits_matroid.pxd index 2c876fa3a48..f7b938a4d6f 100644 --- a/src/sage/matroids/circuits_matroid.pxd +++ b/src/sage/matroids/circuits_matroid.pxd @@ -8,32 +8,30 @@ cdef class CircuitsMatroid(Matroid): cdef dict _k_C # k-circuits (k=len) cdef list _sorted_C_lens cdef bint _nsc_defined - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) cpdef full_rank(self) - cpdef _is_independent(self, X) - cpdef _max_independent(self, X) - cpdef _circuit(self, X) - cpdef _closure(self, X) + cpdef bint _is_independent(self, frozenset X) + cpdef frozenset _max_independent(self, frozenset X) + cpdef frozenset _circuit(self, frozenset X) + cpdef frozenset _closure(self, frozenset X) # enumeration - cpdef bases(self) - cpdef nonbases(self) - cpdef independent_r_sets(self, long r) - cpdef dependent_r_sets(self, long r) - cpdef circuits(self, k=*) - cpdef nonspanning_circuits(self) - cpdef no_broken_circuits_facets(self, ordering=*, reduced=*) - cpdef no_broken_circuits_sets(self, ordering=*, reduced=*) + cpdef SetSystem independent_sets(self, long k=*) + cpdef SetSystem dependent_sets(self, long k) + cpdef SetSystem circuits(self, k=*) + cpdef SetSystem nonspanning_circuits(self) + cpdef SetSystem no_broken_circuits_facets(self, ordering=*, reduced=*) + cpdef SetSystem no_broken_circuits_sets(self, ordering=*, reduced=*) cpdef broken_circuit_complex(self, ordering=*, reduced=*) # properties cpdef girth(self) - cpdef is_paving(self) + cpdef bint is_paving(self) # isomorphism and relabeling cpdef _is_isomorphic(self, other, certificate=*) cpdef relabel(self, mapping) # verification - cpdef is_valid(self) + cpdef bint is_valid(self) diff --git a/src/sage/matroids/circuits_matroid.pyx b/src/sage/matroids/circuits_matroid.pyx index 9c903ca57d5..ae3be51d36f 100644 --- a/src/sage/matroids/circuits_matroid.pyx +++ b/src/sage/matroids/circuits_matroid.pyx @@ -32,8 +32,8 @@ AUTHORS: from cpython.object cimport Py_EQ, Py_NE from sage.structure.richcmp cimport rich_to_bool, richcmp -from .matroid cimport Matroid -from .set_system cimport SetSystem +from sage.matroids.matroid cimport Matroid +from sage.matroids.set_system cimport SetSystem cdef class CircuitsMatroid(Matroid): r""" @@ -67,8 +67,8 @@ cdef class CircuitsMatroid(Matroid): sage: TestSuite(M).run() """ if M is not None: - self._groundset = frozenset(M.groundset()) - self._C = set([C for C in M.circuits()]) + self._groundset = M.groundset() + self._C = set(M.circuits()) else: self._groundset = frozenset(groundset) self._C = set([frozenset(C) for C in circuits]) @@ -84,7 +84,7 @@ cdef class CircuitsMatroid(Matroid): self._matroid_rank = self.rank(self._groundset) self._nsc_defined = nsc_defined - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. @@ -100,7 +100,7 @@ cdef class CircuitsMatroid(Matroid): """ return self._groundset - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): """ Return the rank of a set ``X``. @@ -116,7 +116,7 @@ cdef class CircuitsMatroid(Matroid): EXAMPLES:: sage: M = matroids.Theta(3) - sage: M._rank(['x1', 'y0', 'y2']) + sage: M._rank(frozenset(['x1', 'y0', 'y2'])) 2 """ return len(self._max_independent(X)) @@ -140,7 +140,7 @@ cdef class CircuitsMatroid(Matroid): """ return self._matroid_rank - cpdef _is_independent(self, X): + cpdef bint _is_independent(self, frozenset X): """ Test if input is independent. @@ -154,22 +154,21 @@ cdef class CircuitsMatroid(Matroid): EXAMPLES:: sage: M = matroids.Theta(4) - sage: M._is_independent(['y0', 'y1', 'y3', 'x2']) + sage: M._is_independent(frozenset(['y0', 'y1', 'y3', 'x2'])) False - sage: M._is_independent(['y0', 'y2', 'y3', 'x2']) + sage: M._is_independent(frozenset(['y0', 'y2', 'y3', 'x2'])) True """ - cdef set XX = set(X) - cdef int i, l = len(XX) + cdef int i, l = len(X) for i in self._sorted_C_lens: if i > l: break for C in self._k_C[i]: - if C <= XX: + if C <= X: return False return True - cpdef _max_independent(self, X): + cpdef frozenset _max_independent(self, frozenset X): """ Compute a maximal independent subset. @@ -191,13 +190,13 @@ cdef class CircuitsMatroid(Matroid): cdef frozenset C while True: try: - C = self._circuit(XX) + C = self._circuit(frozenset(XX)) e = next(iter(C)) XX.remove(e) except (ValueError, StopIteration): return frozenset(XX) - cpdef _circuit(self, X): + cpdef frozenset _circuit(self, frozenset X): """ Return a minimal dependent subset. @@ -212,24 +211,23 @@ cdef class CircuitsMatroid(Matroid): EXAMPLES:: sage: M = matroids.Theta(4) - sage: sorted(M._circuit(['y0', 'y1', 'y3', 'x2'])) + sage: sorted(M._circuit(frozenset(['y0', 'y1', 'y3', 'x2']))) ['x2', 'y0', 'y1', 'y3'] - sage: M._circuit(['y0', 'y2', 'y3', 'x2']) + sage: M._circuit(frozenset(['y0', 'y2', 'y3', 'x2'])) Traceback (most recent call last): ... ValueError: no circuit in independent set """ - cdef set XX = set(X) - cdef int i, l = len(XX) + cdef int i, l = len(X) for i in self._sorted_C_lens: if i > l: break for C in self._k_C[i]: - if C <= XX: + if C <= X: return C raise ValueError("no circuit in independent set") - cpdef _closure(self, X): + cpdef frozenset _closure(self, frozenset X): """ Return the closure of a set. @@ -244,7 +242,7 @@ cdef class CircuitsMatroid(Matroid): sage: from sage.matroids.circuits_matroid import CircuitsMatroid sage: M = CircuitsMatroid(matroids.catalog.Vamos()) - sage: sorted(M._closure(set(['a', 'b', 'c']))) + sage: sorted(M._closure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] """ cdef set XX = set(X) @@ -449,29 +447,6 @@ cdef class CircuitsMatroid(Matroid): # enumeration - cpdef bases(self): - r""" - Return the bases of the matroid. - - OUTPUT: :class:`SetSystem` - - EXAMPLES:: - - sage: from sage.matroids.circuits_matroid import CircuitsMatroid - sage: M = CircuitsMatroid(matroids.CompleteGraphic(4)) - sage: len(M.bases()) - 16 - """ - from itertools import combinations - cdef set B = set() - cdef set NB = set(self.nonbases()) - cdef frozenset SS - for S in combinations(self._groundset, self._matroid_rank): - SS = frozenset(S) - if SS not in NB: - B.add(SS) - return SetSystem(self._groundset, B) - def bases_iterator(self): r""" Return an iterator over the bases of the matroid. @@ -492,39 +467,21 @@ cdef class CircuitsMatroid(Matroid): frozenset({2, 3})] """ from itertools import combinations - cdef set B = set() cdef set NB = set(self.nonbases()) cdef frozenset S - for SS in combinations(self._groundset, self._matroid_rank): - S = frozenset(SS) + for St in combinations(self._groundset, self._matroid_rank): + S = frozenset(St) if S not in NB: yield S - cpdef nonbases(self): - r""" - Return the nonbases of the matroid. - - OUTPUT: :class:`SetSystem` - - EXAMPLES:: - - sage: from sage.matroids.circuits_matroid import CircuitsMatroid - sage: M = CircuitsMatroid(matroids.Uniform(2, 4)) - sage: len(M.nonbases()) - 0 - sage: M = CircuitsMatroid(matroids.CompleteGraphic(6)) - sage: len(M.nonbases()) - 1707 - """ - return self.dependent_r_sets(self._matroid_rank) - - cpdef independent_r_sets(self, long r): + cpdef SetSystem independent_sets(self, long k=-1): r""" - Return the size-``r`` independent subsets of the matroid. + Return the independent sets of the matroid. INPUT: - - ``r`` -- nonnegative integer + - ``k`` -- integer (optional); if specified, return the size-`k` + independent sets of the matroid OUTPUT: :class:`SetSystem` @@ -532,34 +489,45 @@ cdef class CircuitsMatroid(Matroid): sage: from sage.matroids.circuits_matroid import CircuitsMatroid sage: M = CircuitsMatroid(matroids.catalog.Pappus()) - sage: M.independent_r_sets(4) + sage: M.independent_sets(4) SetSystem of 0 sets over 9 elements - sage: M.independent_r_sets(3) + sage: M.independent_sets(3) SetSystem of 75 sets over 9 elements sage: frozenset({'a', 'c', 'e'}) in _ True + TESTS:: + + sage: from sage.matroids.circuits_matroid import CircuitsMatroid + sage: M = CircuitsMatroid(matroids.CompleteGraphic(4)) + sage: len(M.bases()) + 16 + .. SEEALSO:: :meth:`M.bases() ` """ + if k == -1: # all independent sets + return self._independent_sets() + + # independent k-sets from itertools import combinations - cdef set I_r = set() - cdef set D_r = set(self.dependent_r_sets(r)) - cdef frozenset SS - for S in combinations(self._groundset, r): - SS = frozenset(S) - if SS not in D_r: - I_r.add(SS) - return SetSystem(self._groundset, I_r) - - cpdef dependent_r_sets(self, long r): + cdef SetSystem I_k = SetSystem(self._groundset) + cdef set D_k = set(self.dependent_sets(k)) + cdef frozenset S + for St in combinations(self._groundset, k): + S = frozenset(St) + if S not in D_k: + I_k.append(S) + return I_k + + cpdef SetSystem dependent_sets(self, long k): r""" - Return the dependent subsets of fixed size. + Return the dependent sets of fixed size. INPUT: - - ``r`` -- nonnegative integer + - ``k`` -- integer OUTPUT: :class:`SetSystem` @@ -567,28 +535,38 @@ cdef class CircuitsMatroid(Matroid): sage: from sage.matroids.circuits_matroid import CircuitsMatroid sage: M = CircuitsMatroid(matroids.catalog.Vamos()) - sage: M.dependent_r_sets(3) + sage: M.dependent_sets(3) SetSystem of 0 sets over 8 elements - sage: sorted([sorted(X) for X in M.dependent_r_sets(4)]) + sage: sorted([sorted(X) for X in M.dependent_sets(4)]) [['a', 'b', 'c', 'd'], ['a', 'b', 'e', 'f'], ['a', 'b', 'g', 'h'], ['c', 'd', 'e', 'f'], ['e', 'f', 'g', 'h']] + + TESTS:: + + sage: from sage.matroids.circuits_matroid import CircuitsMatroid + sage: M = CircuitsMatroid(matroids.Uniform(2, 4)) + sage: len(M.nonbases()) + 0 + sage: M = CircuitsMatroid(matroids.CompleteGraphic(6)) + sage: len(M.nonbases()) + 1707 """ cdef int i - cdef set NB = set() + cdef set D_k = set() cdef frozenset S - for i in range(min(self._k_C), r + 1): + for i in range(min(self._k_C), k + 1): if i in self._k_C: for S in self._k_C[i]: - NB.add(S) - if i == r: + D_k.add(S) + if i == k: break - for S in NB.copy(): - NB.remove(S) + for S in D_k.copy(): + D_k.remove(S) for e in S ^ self._groundset: - NB.add(S | set([e])) - return SetSystem(self._groundset, NB) + D_k.add(S | set([e])) + return SetSystem(self._groundset, D_k) - cpdef circuits(self, k=None): + cpdef SetSystem circuits(self, k=None): """ Return the circuits of the matroid. @@ -612,16 +590,16 @@ cdef class CircuitsMatroid(Matroid): frozenset({0, 2, 3}), frozenset({1, 2, 3})] """ - cdef set C = set() + cdef SetSystem C = SetSystem(self._groundset) if k is not None: if k in self._k_C: for c in self._k_C[k]: - C.add(c) + C.append(c) else: for i in self._k_C: for c in self._k_C[i]: - C.add(c) - return SetSystem(self._groundset, C) + C.append(c) + return C def circuits_iterator(self, k=None): """ @@ -654,7 +632,7 @@ cdef class CircuitsMatroid(Matroid): for C in self._k_C[i]: yield C - cpdef nonspanning_circuits(self): + cpdef SetSystem nonspanning_circuits(self): """ Return the nonspanning circuits of the matroid. @@ -670,12 +648,15 @@ cdef class CircuitsMatroid(Matroid): sage: M.nonspanning_circuits() SetSystem of 15 sets over 10 elements """ - cdef set NSC = set() + cdef SetSystem NSC = SetSystem(self._groundset) cdef int i - for i in self._k_C: - if i <= self._matroid_rank: - NSC.update(self._k_C[i]) - return SetSystem(self._groundset, NSC) + cdef frozenset S + for i in self._sorted_C_lens: + if i > self._matroid_rank: + break + for S in self._k_C[i]: + NSC.append(S) + return NSC def nonspanning_circuits_iterator(self): """ @@ -694,7 +675,7 @@ cdef class CircuitsMatroid(Matroid): for C in self._k_C[i]: yield C - cpdef no_broken_circuits_facets(self, ordering=None, reduced=False): + cpdef SetSystem no_broken_circuits_facets(self, ordering=None, reduced=False): r""" Return the no broken circuits (NBC) facets of ``self``. @@ -746,18 +727,18 @@ cdef class CircuitsMatroid(Matroid): for e in self._groundset ^ S: BC[i+1].add(S | set([e])) - cdef set B = set() - for SS in combinations(ordering[1:], self._matroid_rank - 1): - S = frozenset(SS) + cdef SetSystem B = SetSystem(self._groundset) + for St in combinations(ordering[1:], self._matroid_rank - 1): + S = frozenset(St) if S | min_e not in BC[r]: if not reduced: - B.add(S | min_e) + B.append(S | min_e) else: - B.add(S) + B.append(S) - return SetSystem(self.groundset(), B) + return B - cpdef no_broken_circuits_sets(self, ordering=None, reduced=False): + cpdef SetSystem no_broken_circuits_sets(self, ordering=None, reduced=False): r""" Return the no broken circuits (NBC) sets of ``self``. @@ -799,11 +780,11 @@ cdef class CircuitsMatroid(Matroid): True """ from sage.topology.simplicial_complex import SimplicialComplex - cdef set NBC = set() + cdef SetSystem NBC = SetSystem(self._groundset) for f in SimplicialComplex(self.no_broken_circuits_facets(ordering, reduced), maximality_check=False).face_iterator(): - NBC.add(frozenset(f)) - return SetSystem(self.groundset(), NBC) + NBC.append(frozenset(f)) + return NBC cpdef broken_circuit_complex(self, ordering=None, reduced=False): r""" @@ -869,7 +850,7 @@ cdef class CircuitsMatroid(Matroid): from sage.rings.infinity import infinity return min(self._k_C, default=infinity) - cpdef is_paving(self): + cpdef bint is_paving(self): """ Return if ``self`` is paving. @@ -884,11 +865,11 @@ cdef class CircuitsMatroid(Matroid): sage: M.is_paving() True """ - return self.girth() >= self.rank() + return self.girth() >= self._matroid_rank # verification - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if ``self`` obeys the matroid axioms. @@ -943,7 +924,6 @@ cdef class CircuitsMatroid(Matroid): # check circuit elimination axiom U12 = C1 | C2 for e in I12: - S = U12 - {e} - if self._is_independent(S): + if self._is_independent(U12 - {e}): return False return True diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 9a44462fed3..c4df0334e68 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -112,13 +112,13 @@ from sage.rings.finite_rings.finite_field_base import FiniteField import sage.matroids.matroid import sage.matroids.basis_exchange_matroid -from .rank_matroid import RankMatroid -from .circuits_matroid import CircuitsMatroid -from .flats_matroid import FlatsMatroid -from .circuit_closures_matroid import CircuitClosuresMatroid -from .basis_matroid import BasisMatroid -from .linear_matroid import LinearMatroid, RegularMatroid, BinaryMatroid, TernaryMatroid, QuaternaryMatroid -from .graphic_matroid import GraphicMatroid +from sage.matroids.rank_matroid import RankMatroid +from sage.matroids.circuits_matroid import CircuitsMatroid +from sage.matroids.flats_matroid import FlatsMatroid +from sage.matroids.circuit_closures_matroid import CircuitClosuresMatroid +from sage.matroids.basis_matroid import BasisMatroid +from sage.matroids.linear_matroid import LinearMatroid, RegularMatroid, BinaryMatroid, TernaryMatroid, QuaternaryMatroid +from sage.matroids.graphic_matroid import GraphicMatroid import sage.matroids.utilities @@ -510,7 +510,7 @@ def Matroid(groundset=None, data=None, **kwds): sage: Matroid([0, 1, 2], [[1, 0, 1], [0, 1, 1]]) Traceback (most recent call last): ... - ValueError: basis has wrong cardinality. + ValueError: basis has wrong cardinality If the groundset size equals number of rows plus number of columns, an identity matrix is prepended. Otherwise the groundset size must equal @@ -634,7 +634,7 @@ def Matroid(groundset=None, data=None, **kwds): sage: M = Matroid(circuit_closures=[(2, 'abd'), (3, 'abcdef'), ....: (2, 'bce')]) - sage: M.equals(matroids.catalog.Q6()) # needs sage.rings.finite_rings + sage: M.equals(matroids.catalog.Q6()) # needs sage.rings.finite_rings True #. RevLex-Index: diff --git a/src/sage/matroids/database_matroids.py b/src/sage/matroids/database_matroids.py index 50d781d349f..e964ee4836c 100644 --- a/src/sage/matroids/database_matroids.py +++ b/src/sage/matroids/database_matroids.py @@ -913,7 +913,7 @@ def L8(groundset=None): sage: K4 = matroids.catalog.K4(range(6)) sage: Bext = [list(b) for b in K4.bases()] + [list(I)+[6] for I in - ....: K4.independent_r_sets(2)] + ....: K4.independent_sets(2)] sage: K4ext = Matroid(bases=Bext) sage: import random sage: e = random.choice(list(M.groundset())) @@ -1236,6 +1236,7 @@ def K33dual(groundset='abcdefghi'): EXAMPLES:: + sage: # needs sage.graphs sage: M = matroids.catalog.K33dual(); M M*(K3, 3): Regular matroid of rank 4 on 9 elements with 81 bases sage: any(N.is_3connected() for N in M.linear_extensions(simple=True)) @@ -1266,6 +1267,7 @@ def K33(groundset='abcdefghi'): EXAMPLES:: + sage: # needs sage.graphs sage: M = matroids.catalog.K33(); M M(K3, 3): Regular matroid of rank 5 on 9 elements with 81 bases sage: M.is_valid() diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index d17246ad2c5..76ad7aaa600 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -51,7 +51,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from .matroid import Matroid +from sage.matroids.matroid import Matroid class DualMatroid(Matroid): r""" @@ -143,7 +143,7 @@ def _rank(self, X): EXAMPLES:: sage: M = matroids.catalog.NonPappus().dual() - sage: M._rank(['a', 'b', 'c']) + sage: M._rank(frozenset(['a', 'b', 'c'])) 3 """ return self._matroid._corank(X) @@ -162,7 +162,7 @@ def _corank(self, X): EXAMPLES:: sage: M = matroids.catalog.Vamos().dual() - sage: M._corank(set(['a', 'e', 'g', 'd', 'h'])) + sage: M._corank(frozenset(['a', 'e', 'g', 'd', 'h'])) 4 """ return self._matroid._rank(X) @@ -181,12 +181,13 @@ def _max_independent(self, X): EXAMPLES:: sage: M = matroids.catalog.Vamos().dual() - sage: X = M._max_independent(set(['a', 'c', 'd', 'e', 'f'])) + sage: X = M._max_independent(frozenset(['a', 'c', 'd', 'e', 'f'])) sage: sorted(X) # random ['a', 'c', 'd', 'e'] sage: M.is_independent(X) True - sage: all(M.is_dependent(X.union([y])) for y in M.groundset() if y not in X) + sage: all(M.is_dependent(X.union([y])) for y in M.groundset() + ....: if y not in X) True """ return self._matroid._max_coindependent(X) @@ -207,10 +208,10 @@ def _circuit(self, X): sage: M = matroids.catalog.Vamos().dual() sage: sorted(sage.matroids.matroid.Matroid._circuit(M, - ....: set(['a', 'c', 'd', 'e', 'f']))) + ....: frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] sage: sorted(sage.matroids.matroid.Matroid._circuit(M, - ....: set(['a', 'c', 'd']))) + ....: frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no circuit in independent set. @@ -231,7 +232,7 @@ def _closure(self, X): EXAMPLES:: sage: M = matroids.catalog.Vamos().dual() - sage: sorted(M._closure(set(['a', 'b', 'c']))) + sage: sorted(M._closure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] """ return self._matroid._coclosure(X) @@ -250,12 +251,13 @@ def _max_coindependent(self, X): EXAMPLES:: sage: M = matroids.catalog.Vamos().dual() - sage: X = M._max_coindependent(set(['a', 'c', 'd', 'e', 'f'])) + sage: X = M._max_coindependent(frozenset(['a', 'c', 'd', 'e', 'f'])) sage: sorted(X) # random ['a', 'd', 'e', 'f'] sage: M.is_coindependent(X) True - sage: all(M.is_codependent(X.union([y])) for y in M.groundset() if y not in X) + sage: all(M.is_codependent(X.union([y])) for y in M.groundset() + ....: if y not in X) True """ return self._matroid._max_independent(X) @@ -274,7 +276,7 @@ def _coclosure(self, X): EXAMPLES:: sage: M = matroids.catalog.Vamos().dual() - sage: sorted(M._coclosure(set(['a', 'b', 'c']))) + sage: sorted(M._coclosure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] """ return self._matroid._closure(X) @@ -294,9 +296,9 @@ def _cocircuit(self, X): EXAMPLES:: sage: M = matroids.catalog.Vamos().dual() - sage: sorted(M._cocircuit(set(['a', 'c', 'd', 'e', 'f']))) + sage: sorted(M._cocircuit(frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] - sage: sorted(M._cocircuit(set(['a', 'c', 'd']))) + sage: sorted(M._cocircuit(frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no circuit in independent set diff --git a/src/sage/matroids/flats_matroid.pxd b/src/sage/matroids/flats_matroid.pxd index 28a6d22deaf..956e30f859d 100644 --- a/src/sage/matroids/flats_matroid.pxd +++ b/src/sage/matroids/flats_matroid.pxd @@ -1,24 +1,27 @@ -from .matroid cimport Matroid +from sage.matroids.matroid cimport Matroid +from sage.matroids.set_system cimport SetSystem cdef class FlatsMatroid(Matroid): cdef frozenset _groundset cdef int _matroid_rank cdef dict _F # flats cdef object _L # lattice of flats - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + + cpdef int _rank(self, frozenset X) + cpdef frozenset _closure(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) + cpdef full_rank(self) - cpdef _closure(self, X) - cpdef _is_closed(self, X) # enumeration - cpdef flats(self, k) - cpdef whitney_numbers(self) - cpdef whitney_numbers2(self) + cpdef SetSystem flats(self, long k) + cpdef list whitney_numbers(self) + cpdef list whitney_numbers2(self) # isomorphism and relabeling cpdef _is_isomorphic(self, other, certificate=*) cpdef relabel(self, mapping) # verification - cpdef is_valid(self) + cpdef bint is_valid(self) diff --git a/src/sage/matroids/flats_matroid.pyx b/src/sage/matroids/flats_matroid.pyx index 71a046b42a1..dce9d8756fa 100644 --- a/src/sage/matroids/flats_matroid.pyx +++ b/src/sage/matroids/flats_matroid.pyx @@ -32,8 +32,8 @@ AUTHORS: from cpython.object cimport Py_EQ, Py_NE from sage.structure.richcmp cimport rich_to_bool, richcmp -from .matroid cimport Matroid -from .set_system cimport SetSystem +from sage.matroids.matroid cimport Matroid +from sage.matroids.set_system cimport SetSystem from sage.combinat.posets.lattices import LatticePoset, FiniteLatticePoset cdef class FlatsMatroid(Matroid): @@ -97,7 +97,7 @@ cdef class FlatsMatroid(Matroid): self._F[self._L.rank(x)].add(x) self._matroid_rank = max(self._F, default=-1) - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. @@ -114,7 +114,7 @@ cdef class FlatsMatroid(Matroid): """ return self._groundset - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): """ Return the rank of a set ``X``. @@ -167,7 +167,7 @@ cdef class FlatsMatroid(Matroid): """ return self._matroid_rank - cpdef _closure(self, X): + cpdef frozenset _closure(self, frozenset X): """ Return the closure of a set. @@ -191,7 +191,7 @@ cdef class FlatsMatroid(Matroid): if f >= X: return f - cpdef _is_closed(self, X): + cpdef bint _is_closed(self, frozenset X): """ Test if input is a closed set. @@ -409,7 +409,7 @@ cdef class FlatsMatroid(Matroid): # enumeration - cpdef flats(self, k): + cpdef SetSystem flats(self, long k): r""" Return the flats of the matroid of specified rank. @@ -470,7 +470,7 @@ cdef class FlatsMatroid(Matroid): self._L = LatticePoset((flats, lambda x, y: x < y)) return self._L - cpdef whitney_numbers(self): + cpdef list whitney_numbers(self): r""" Return the Whitney numbers of the first kind of the matroid. @@ -509,7 +509,7 @@ cdef class FlatsMatroid(Matroid): w[self._L.rank(F)] += mu[0, i] return w - cpdef whitney_numbers2(self): + cpdef list whitney_numbers2(self): r""" Return the Whitney numbers of the second kind of the matroid. @@ -540,7 +540,7 @@ cdef class FlatsMatroid(Matroid): # verification - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if ``self`` obeys the matroid axioms. diff --git a/src/sage/matroids/graphic_matroid.pxd b/src/sage/matroids/graphic_matroid.pxd index ced452ad963..8ec8dd9e8b0 100644 --- a/src/sage/matroids/graphic_matroid.pxd +++ b/src/sage/matroids/graphic_matroid.pxd @@ -1,4 +1,4 @@ -from .matroid cimport Matroid +from sage.matroids.matroid cimport Matroid from sage.graphs.generic_graph_pyx cimport GenericGraph_pyx cdef class GraphicMatroid(Matroid): @@ -6,25 +6,27 @@ cdef class GraphicMatroid(Matroid): cdef readonly GenericGraph_pyx _G cdef dict _vertex_map cdef dict _groundset_edge_map - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) cpdef _vertex_stars(self) cpdef _minor(self, contractions, deletions) cpdef _has_minor(self, N, bint certificate=*) - cpdef _corank(self, X) - cpdef _is_circuit(self, X) - cpdef _closure(self, X) - cpdef _max_independent(self, X) - cpdef _max_coindependent(self, X) - cpdef _circuit(self, X) - cpdef _coclosure(self, X) - cpdef _is_closed(self, X) + cpdef int _corank(self, frozenset X) + cpdef bint _is_circuit(self, frozenset X) + cpdef frozenset _closure(self, frozenset X) + cpdef frozenset _max_independent(self, frozenset X) + cpdef frozenset _max_coindependent(self, frozenset X) + cpdef frozenset _circuit(self, frozenset X) + cpdef frozenset _coclosure(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) cpdef _is_isomorphic(self, other, certificate=*) cpdef _isomorphism(self, other) - cpdef is_valid(self) + cpdef bint is_valid(self) + cpdef bint is_graphic(self) + cpdef bint is_regular(self) cpdef graph(self) cpdef vertex_map(self) - cpdef groundset_to_edges(self, X) + cpdef list groundset_to_edges(self, X) cpdef _groundset_to_edges(self, X) cpdef subgraph_from_set(self, X) cpdef _subgraph_from_set(self, X) @@ -33,3 +35,4 @@ cdef class GraphicMatroid(Matroid): cpdef twist(self, X) cpdef one_sum(self, X, u, v) cpdef regular_matroid(self) + cpdef relabel(self, mapping) diff --git a/src/sage/matroids/graphic_matroid.pyx b/src/sage/matroids/graphic_matroid.pyx index e55502571b1..13ceb7d77ce 100644 --- a/src/sage/matroids/graphic_matroid.pyx +++ b/src/sage/matroids/graphic_matroid.pyx @@ -24,7 +24,7 @@ Graphic matroids do not have a representation matrix or any of the functionality of regular matroids. It is possible to get an instance of the :class:`~sage.matroids.linear_matroid.RegularMatroid` class by using the ``regular`` keyword when constructing the matroid. It is also possible to cast -a class:`GraphicMatroid` as a class:`RegularMatroid` with the +a :class:`GraphicMatroid` as a :class:`RegularMatroid` with the :meth:`~sage.matroids.graphic_matroids.GraphicMatroid.regular_matroid` method:: @@ -86,9 +86,9 @@ AUTHORS: # https://www.gnu.org/licenses/ # **************************************************************************** -from .matroid cimport Matroid +from sage.matroids.matroid cimport Matroid from copy import copy, deepcopy -from .utilities import newlabel, split_vertex, sanitize_contractions_deletions +from sage.matroids.utilities import newlabel, split_vertex, sanitize_contractions_deletions from itertools import combinations from sage.rings.integer import Integer from sage.sets.disjoint_set cimport DisjointSet_of_hashables @@ -99,14 +99,14 @@ cdef class GraphicMatroid(Matroid): INPUT: - - ``G`` -- class:`Graph` + - ``G`` -- :class:`Graph` - ``groundset`` -- list (optional); in 1-1 correspondence with ``G.edge_iterator()`` - OUTPUT: class:`GraphicMatroid` where the groundset elements are the edges of `G` + OUTPUT: :class:`GraphicMatroid` where the groundset elements are the edges of `G` .. NOTE:: - If a disconnected graph is given as input, the instance of class:`GraphicMatroid` + If a disconnected graph is given as input, the instance of :class:`GraphicMatroid` will connect the graph components and store this as its graph. EXAMPLES:: @@ -220,7 +220,7 @@ cdef class GraphicMatroid(Matroid): # The edge labels should already be the elements. self._groundset_edge_map = ({l: (u, v) for (u, v, l) in self._G.edge_iterator()}) - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid as a frozenset. @@ -238,7 +238,7 @@ cdef class GraphicMatroid(Matroid): """ return self._groundset - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): """ Return the rank of a set ``X``. @@ -452,7 +452,7 @@ cdef class GraphicMatroid(Matroid): sage: loads(dumps(M)) Graphic matroid of rank 9 on 15 elements """ - from .unpickling import unpickle_graphic_matroid + from sage.matroids.unpickling import unpickle_graphic_matroid data = (self._G, self.get_custom_name()) version = 0 return unpickle_graphic_matroid, (version, data) @@ -471,7 +471,7 @@ cdef class GraphicMatroid(Matroid): Assumptions: contractions are independent, deletions are coindependent, contractions and deletions are disjoint. - OUTPUT: class:`GraphicMatroid` + OUTPUT: :class:`GraphicMatroid` EXAMPLES:: @@ -625,7 +625,7 @@ cdef class GraphicMatroid(Matroid): N = N.regular_matroid() return M._has_minor(N, certificate=certificate) - cpdef _corank(self, X): + cpdef int _corank(self, frozenset X): """ Return the corank of the set `X` in the matroid. @@ -640,9 +640,9 @@ cdef class GraphicMatroid(Matroid): EXAMPLES:: sage: M = Matroid(range(9), graphs.CompleteBipartiteGraph(3,3)) - sage: M._corank([0,1,2]) + sage: M._corank(frozenset([0,1,2])) 2 - sage: M._corank([1,2,3]) + sage: M._corank(frozenset([1,2,3])) 3 """ cdef DisjointSet_of_hashables DS_vertices @@ -653,7 +653,7 @@ cdef class GraphicMatroid(Matroid): DS_vertices.union(u, v) return len(X) - (DS_vertices.number_of_subsets() - Integer(1)) - cpdef _is_circuit(self, X): + cpdef bint _is_circuit(self, frozenset X): """ Test if input is a circuit. @@ -666,17 +666,17 @@ cdef class GraphicMatroid(Matroid): EXAMPLES:: sage: M = Matroid(range(5), graphs.DiamondGraph()) - sage: M._is_circuit([0,1,2]) + sage: M._is_circuit(frozenset([0,1,2])) True - sage: M._is_circuit([0,1,2,3]) + sage: M._is_circuit(frozenset([0,1,2,3])) False - sage: M._is_circuit([0,1,3]) + sage: M._is_circuit(frozenset([0,1,3])) False """ cdef GenericGraph_pyx g = self._subgraph_from_set(X) return g.is_cycle() - cpdef _closure(self, X): + cpdef frozenset _closure(self, frozenset X): """ Return the closure of a set. @@ -689,9 +689,9 @@ cdef class GraphicMatroid(Matroid): EXAMPLES:: sage: M = Matroid(range(5), graphs.DiamondGraph()) - sage: sorted(M._closure([0])) + sage: sorted(M._closure(frozenset([0]))) [0] - sage: sorted(M._closure([0,1])) + sage: sorted(M._closure(frozenset([0,1]))) [0, 1, 2] sage: sorted(M._closure(M.groundset())) [0, 1, 2, 3, 4] @@ -704,16 +704,15 @@ cdef class GraphicMatroid(Matroid): sage: M = Matroid(range(6), Graph(edgelist, loops=True, multiedges=True)) sage: M.graph().edges(sort=True) [(0, 0, 0), (0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 2, 4), (1, 2, 5)] - sage: sorted(M._closure([4])) + sage: sorted(M._closure(frozenset([4]))) [0, 4, 5] """ cdef set XX = set(X) - cdef frozenset Y = self._groundset.difference(XX) + cdef frozenset Y = self.groundset().difference(XX) cdef list edgelist = self._groundset_to_edges(Y) cdef GenericGraph_pyx g = self._subgraph_from_set(XX) cdef list V = g.vertices(sort=False) cdef int components = g.connected_components_number() - cdef tuple e for e in edgelist: # a non-loop edge is in the closure iff both its vertices are # in the induced subgraph, and the edge doesn't connect components @@ -727,7 +726,7 @@ cdef class GraphicMatroid(Matroid): XX.update(set([l for (u, v, l) in self._G.loops()])) return frozenset(XX) - cpdef _max_independent(self, X): + cpdef frozenset _max_independent(self, frozenset X): """ Compute a maximal independent subset. @@ -766,7 +765,7 @@ cdef class GraphicMatroid(Matroid): our_set.add(l) return frozenset(our_set) - cpdef _max_coindependent(self, X): + cpdef frozenset _max_coindependent(self, frozenset X): """ Compute a maximal coindependent subset. @@ -781,10 +780,10 @@ cdef class GraphicMatroid(Matroid): sage: M = Matroid(range(5), graphs.DiamondGraph()) sage: sorted(M._max_coindependent(M.groundset())) [2, 4] - sage: sorted(M._max_coindependent([2,3,4])) + sage: sorted(M._max_coindependent(frozenset([2,3,4]))) [2, 4] sage: N = M.graphic_extension(0, element=5) - sage: sorted(N.max_coindependent([0,1,2,5])) + sage: sorted(N.max_coindependent(frozenset([0,1,2,5]))) [1, 2, 5] """ cdef DisjointSet_of_hashables DS_vertices @@ -804,7 +803,7 @@ cdef class GraphicMatroid(Matroid): DS_vertices.union(u, v) return frozenset(our_set) - cpdef _circuit(self, X): + cpdef frozenset _circuit(self, frozenset X): """ Return a minimal dependent subset. @@ -821,9 +820,9 @@ cdef class GraphicMatroid(Matroid): sage: sorted(M._circuit(M.groundset())) [0, 1, 2] sage: N = Matroid(range(9), graphs.CompleteBipartiteGraph(3,3)) - sage: sorted(N._circuit([0, 1, 2, 6, 7, 8])) + sage: sorted(N._circuit(frozenset([0, 1, 2, 6, 7, 8]))) [0, 1, 6, 7] - sage: N._circuit([0, 1, 2]) + sage: N._circuit(frozenset([0, 1, 2])) Traceback (most recent call last): ... ValueError: no circuit in independent set @@ -883,7 +882,7 @@ cdef class GraphicMatroid(Matroid): return frozenset([l for (u, v, l) in edge_set]) - cpdef _coclosure(self, X): + cpdef frozenset _coclosure(self, frozenset X): """ Return the coclosure of a set. @@ -896,15 +895,15 @@ cdef class GraphicMatroid(Matroid): EXAMPLES:: sage: M = Matroid(range(5), graphs.DiamondGraph()) - sage: sorted(M._coclosure([0])) + sage: sorted(M._coclosure(frozenset([0]))) [0, 1] - sage: sorted(M._coclosure([0,1])) + sage: sorted(M._coclosure(frozenset([0,1]))) [0, 1] sage: N = M.graphic_extension(0, element=5) - sage: sorted(N._coclosure([3])) + sage: sorted(N._coclosure(frozenset([3]))) [3, 4] sage: N = M.graphic_coextension(0, element=5) - sage: sorted(N._coclosure([3])) + sage: sorted(N._coclosure(frozenset([3]))) [3, 4, 5] """ cdef GenericGraph_pyx g = self.graph() @@ -919,7 +918,7 @@ cdef class GraphicMatroid(Matroid): g.add_edge(e) return frozenset(XX) - cpdef _is_closed(self, X): + cpdef bint _is_closed(self, frozenset X): """ Test if input is a closed set. @@ -1094,7 +1093,7 @@ cdef class GraphicMatroid(Matroid): """ return self.is_isomorphic(other, certificate=True)[1] - cpdef is_valid(self): + cpdef bint is_valid(self): """ Test if the data obey the matroid axioms. @@ -1111,11 +1110,11 @@ cdef class GraphicMatroid(Matroid): """ return True - def is_graphic(self): + cpdef bint is_graphic(self): r""" Return if ``self`` is graphic. - This is trivially ``True`` for a class:`GraphicMatroid`. + This is trivially ``True`` for a :class:`GraphicMatroid`. EXAMPLES:: @@ -1125,11 +1124,11 @@ cdef class GraphicMatroid(Matroid): """ return True - def is_regular(self): + cpdef bint is_regular(self): r""" Return if ``self`` is regular. - This is always ``True`` for a class:`GraphicMatroid`. + This is always ``True`` for a :class:`GraphicMatroid`. EXAMPLES:: @@ -1195,7 +1194,7 @@ cdef class GraphicMatroid(Matroid): """ return copy(self._vertex_map) - cpdef groundset_to_edges(self, X): + cpdef list groundset_to_edges(self, X): """ Return a list of edges corresponding to a set of groundset elements. @@ -1298,7 +1297,7 @@ cdef class GraphicMatroid(Matroid): OUTPUT: - A class:`GraphicMatroid` with the specified element added. Note that if + A :class:`GraphicMatroid` with the specified element added. Note that if ``v`` is not specified or if ``v`` is ``u``, then the new element will be a loop. If the new element's label is not specified, it will be generated automatically. @@ -1370,7 +1369,7 @@ cdef class GraphicMatroid(Matroid): OUTPUT: - An iterable containing instances of class:`GraphicMatroid`. If + An iterable containing instances of :class:`GraphicMatroid`. If ``vertices`` is not specified, every vertex is used. .. NOTE:: @@ -1445,7 +1444,7 @@ cdef class GraphicMatroid(Matroid): OUTPUT: - An instance of class:`GraphicMatroid` coextended by the new element. + An instance of :class:`GraphicMatroid` coextended by the new element. If ``X`` is not specified, the new element will be a coloop. .. NOTE:: @@ -1579,7 +1578,7 @@ cdef class GraphicMatroid(Matroid): OUTPUT: - An iterable containing instances of class:`GraphicMatroid`. If + An iterable containing instances of :class:`GraphicMatroid`. If ``vertices`` is not specified, the method iterates over all vertices. EXAMPLES:: @@ -1721,7 +1720,7 @@ cdef class GraphicMatroid(Matroid): - ``X`` -- the set of elements to be twisted with respect to the rest of the matroid - OUTPUT: class:`GraphicMatroid` isomorphic to this matroid but + OUTPUT: :class:`GraphicMatroid` isomorphic to this matroid but with a graph that is not necessarily isomorphic EXAMPLES:: @@ -1831,7 +1830,7 @@ cdef class GraphicMatroid(Matroid): - ``u`` -- vertex spanned by the edges of the elements in ``X`` - ``v`` -- vertex spanned by the edges of the elements not in ``X`` - OUTPUT: class:`GraphicMatroid` isomorphic to this matroid but + OUTPUT: :class:`GraphicMatroid` isomorphic to this matroid but with a graph that is not necessarily isomorphic EXAMPLES:: @@ -1950,8 +1949,8 @@ cdef class GraphicMatroid(Matroid): cpdef regular_matroid(self): """ - Return an instance of class:`RegularMatroid` isomorphic to this - class:`GraphicMatroid`. + Return an instance of :class:`RegularMatroid` isomorphic to this + :class:`GraphicMatroid`. EXAMPLES:: @@ -1978,7 +1977,7 @@ cdef class GraphicMatroid(Matroid): X = [l for u, v, l in self._G.edge_iterator()] return ConstructorMatroid(groundset=X, graph=self._G, regular=True) - def relabel(self, mapping): + cpdef relabel(self, mapping): r""" Return an isomorphic matroid with relabeled groundset. diff --git a/src/sage/matroids/linear_matroid.pxd b/src/sage/matroids/linear_matroid.pxd index 76027b61a9f..085a68be0f6 100644 --- a/src/sage/matroids/linear_matroid.pxd +++ b/src/sage/matroids/linear_matroid.pxd @@ -62,7 +62,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef _is_3connected_shifting(self, certificate=*) cpdef _is_4connected_shifting(self, certificate=*) - cpdef is_valid(self) + cpdef bint is_valid(self) cdef class BinaryMatroid(LinearMatroid): cdef tuple _b_invariant, _b_partition @@ -91,8 +91,8 @@ cdef class BinaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef is_graphic(self) - cpdef is_valid(self) + cpdef bint is_graphic(self) + cpdef bint is_valid(self) cdef class TernaryMatroid(LinearMatroid): @@ -122,7 +122,7 @@ cdef class TernaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef is_valid(self) + cpdef bint is_valid(self) cdef class QuaternaryMatroid(LinearMatroid): cdef object _x_zero, _x_one @@ -149,7 +149,7 @@ cdef class QuaternaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef is_valid(self) + cpdef bint is_valid(self) cdef class RegularMatroid(LinearMatroid): cdef _bases_count, _r_invariant @@ -172,5 +172,6 @@ cdef class RegularMatroid(LinearMatroid): cpdef has_line_minor(self, k, hyperlines=*, certificate=*) cpdef _linear_extension_chains(self, F, fundamentals=*) - cpdef is_graphic(self) - cpdef is_valid(self) + cpdef bint is_regular(self) + cpdef bint is_graphic(self) + cpdef bint is_valid(self) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 9efceb81b75..e1c3bd67a91 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -1,7 +1,7 @@ r""" Linear matroids -When `A` is an `r` times `E` matrix, the linear matroid `M[A]` has ground set +When `A` is an `r` times `E` matrix, the linear matroid `M[A]` has groundset `E` and, for independent sets, all `F` subset of `E` such that the columns of `M[A]` indexed by `F` are linearly independent. @@ -843,14 +843,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A matroid instance, assumed to have the same base - ring as ``self``. + - ``other`` -- matroid; assumed to have the same base ring as ``self`` - ``morphism`` -- a dictionary mapping the groundset of ``self`` to - the groundset of ``other``. - - OUTPUT: + the groundset of ``other`` - Boolean. + OUTPUT: boolean .. WARNING:: @@ -931,11 +928,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid - OUTPUT: - - Boolean. + OUTPUT: boolean .. SEEALSO:: @@ -1020,15 +1015,13 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid - ``morphism`` -- A map from the groundset of ``self`` to the groundset of ``other``. See documentation of the :meth:`M.is_isomorphism() ` method for more on what is accepted as input. - OUTPUT: - - Boolean. + OUTPUT: boolean .. SEEALSO:: @@ -1150,11 +1143,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid - OUTPUT: - - Boolean. + OUTPUT: boolean .. SEEALSO:: @@ -1323,10 +1314,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` .. NOTE:: @@ -1365,7 +1356,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): r""" Return the dual of the matroid. - Let `M` be a matroid with ground set `E`. If `B` is the set of bases + Let `M` be a matroid with groundset `E`. If `B` is the set of bases of `M`, then the set `\{E - b : b \in B\}` is the set of bases of another matroid, the *dual* of `M`. @@ -1452,11 +1443,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``N`` -- A matroid. - - OUTPUT: + - ``N`` -- matroid - Boolean. + OUTPUT: boolean .. SEEALSO:: @@ -1566,6 +1555,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): sage: frozenset(v.keys()) == M.fundamental_circuit([0, 1], 3) True """ + B = frozenset(B) if e in B or not self._is_basis(B): return None self._move_current_basis(B, set()) @@ -1612,6 +1602,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): sage: frozenset(v.keys()) == M.fundamental_cocircuit([0, 1], 0) True """ + B = frozenset(B) if e not in B or not self._is_basis(B): return None self._move_current_basis(B, set()) @@ -1884,13 +1875,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``x`` -- an element of the ground set + - ``x`` -- an element of the groundset - ``fundamentals`` -- a subset of the base ring - ``hyperlines`` (optional) -- a set of flats of rank=full_rank-2 - OUTPUT: - - Boolean. ``True`` if each cross ratio using ``x`` is an element of + OUTPUT: boolean ``True`` if each cross ratio using ``x`` is an element of ``fundamentals``. If ``hyperlines`` is specified, then the method tests if each cross ratio in a minor that arises by contracting a flat ``F`` in ``hyperlines`` and uses ``x`` is in ``fundamentals``. If @@ -1939,7 +1928,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``col`` -- (default: ``None``) a column to be appended to ``self.representation()``. Can be any iterable. - ``chain`` -- (default: ``None``) a dictionary that maps elements of - the ground set to elements of the base ring. + the groundset to elements of the base ring. OUTPUT: @@ -2019,7 +2008,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``row`` -- (default: ``None``) a row to be appended to ``self.representation()``. Can be any iterable. - ``cochain`` -- (default: ``None``) a dictionary that maps elements - of the ground set to elements of the base ring. + of the groundset to elements of the base ring. OUTPUT: @@ -2105,7 +2094,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``element`` -- the name of the new element. - ``chains`` -- a list of dictionaries, each of which maps elements of - the ground set to elements of the base ring. + the groundset to elements of the base ring. OUTPUT: @@ -2153,7 +2142,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``element`` -- the name of the new element. - ``cochains`` -- a list of dictionaries, each of which maps elements - of the ground set to elements of the base ring. + of the groundset to elements of the base ring. OUTPUT: @@ -2207,7 +2196,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): if fundamentals is None: values = R else: # generate only chains that satisfy shallow test for 'crossratios in fundamentals' - T = set(c.keys()) + T = frozenset(c.keys()) if not self._is_independent(T | set([f])): raise ValueError("_extend_chains can only extend chains with basic support") self._move_current_basis(T | set([f]), set()) @@ -2277,17 +2266,17 @@ cdef class LinearMatroid(BasisExchangeMatroid): sage: M = Matroid(reduced_matrix=Matrix(GF(2), [[1, 1, 0], ....: [1, 0, 1], [0, 1, 1]])) - sage: len(M._linear_extension_chains(F=set([0, 1, 2]))) + sage: len(M._linear_extension_chains(F=frozenset([0, 1, 2]))) 8 - sage: M._linear_extension_chains(F=set()) + sage: M._linear_extension_chains(F=frozenset()) [{}] - sage: M._linear_extension_chains(F=set([1])) + sage: M._linear_extension_chains(F=frozenset([1])) [{}, {1: 1}] - sage: len(M._linear_extension_chains(F=set([0, 1]))) + sage: len(M._linear_extension_chains(F=frozenset([0, 1]))) 4 sage: N = Matroid(ring=QQ, reduced_matrix=[[1, 1, 0], ....: [1, 0, 1], [0, 1, 1]]) - sage: N._linear_extension_chains(F=set([0, 1]), + sage: N._linear_extension_chains(F=frozenset([0, 1]), ....: fundamentals=set([1, -1, 1/2, 2])) [{0: 1}, {}, {0: 1, 1: 1}, {0: -1, 1: 1}, {1: 1}] """ @@ -2299,7 +2288,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): C = self.components() if len(C) == 1: for f in F: - sf = set([f]) + sf = frozenset([f]) ff = self._closure(sf) M = self._minor(contractions=sf, deletions=ff - sf) if M.is_connected(): @@ -2341,7 +2330,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``F`` -- (default: ``self.groundset()``) a subset of the groundset. - - ``simple`` -- (default: ``False``) a boolean variable. + - ``simple`` -- (default: ``False``) boolean - ``fundamentals`` -- (default: ``None``) a set elements of the base ring. @@ -2441,7 +2430,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``F`` -- (default: ``self.groundset()``) a subset of the groundset. - - ``cosimple`` -- (default: ``False``) a boolean variable. + - ``cosimple`` -- (default: ``False``) boolean - ``fundamentals`` -- (default: ``None``) a set elements of the base ring. @@ -2494,8 +2483,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``element`` -- (default: ``None``) the name of the new element of the groundset. - - ``F`` -- (default: ``None``) a subset of the ground set. - - ``simple`` -- (default: ``False``) a boolean variable. + - ``F`` -- (default: ``None``) a subset of the groundset. + - ``simple`` -- (default: ``False``) boolean - ``fundamentals`` -- (default: ``None``) a set elements of the base ring. @@ -2562,8 +2551,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): - ``element`` -- (default: ``None``) the name of the new element of the groundset. - - ``F`` -- (default: ``None``) a subset of the ground set. - - ``cosimple`` -- (default: ``False``) a boolean variable. + - ``F`` -- (default: ``None``) a subset of the groundset. + - ``cosimple`` -- (default: ``False``) boolean - ``fundamentals`` -- (default: ``None``) a set elements of the base ring. @@ -2624,7 +2613,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cochains = self.linear_coextension_cochains(F, cosimple=cosimple, fundamentals=fundamentals) return self._linear_coextensions(element, cochains) - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data represent an actual matroid. @@ -2682,7 +2671,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``certificate`` -- (default: ``False``) a boolean; if ``True``, + - ``certificate`` -- (default: ``False``) boolean; if ``True``, then return ``True, None`` if the matroid is 3-connected, and ``False,`` `X` otherwise, where `X` is a `<3`-separation @@ -2723,7 +2712,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): return False, self.components()[0] else: return False - if self.rank()>self.size()-self.rank(): + if self.rank() > self.size() - self.rank(): return self.dual()._is_3connected_shifting(certificate) # the partial matrix @@ -2732,10 +2721,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): X, Y = self._current_rows_cols() # create mapping between elements and columns - dX = dict(zip(range(len(X)),X)) - dY = dict(zip(range(len(Y)),Y)) + dX = dict(zip(range(len(X)), X)) + dY = dict(zip(range(len(Y)), Y)) - for (x,y) in spanning_forest(M): + for (x, y) in spanning_forest(M): P_rows=[x] P_cols=[y] Q_rows=[] @@ -2761,7 +2750,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - - ``certificate`` -- (default: ``False``) a boolean; if ``True``, + - ``certificate`` -- (default: ``False``) boolean; if ``True``, then return ``True, None`` if the matroid is 4-connected, and ``False,`` `X` otherwise, where `X` is a `<4`-separation @@ -2869,7 +2858,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): INPUT: - ``R`` -- (default: the base ring of ``self``) the base ring - - ``ordering`` -- (optional) an ordering of the ground set + - ``ordering`` -- (optional) an ordering of the groundset .. SEEALSO:: @@ -2893,8 +2882,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): sage: # needs sage.groups sage: G = SymmetricGroup(4) sage: action = lambda g, x: g(x + 1) - 1 - sage: OTG1 = M.orlik_terao_algebra(QQ, invariant=(G,action)) - sage: OTG2 = M.orlik_terao_algebra(QQ, invariant=(action,G)) + sage: OTG1 = M.orlik_terao_algebra(QQ, invariant=(G, action)) + sage: OTG2 = M.orlik_terao_algebra(QQ, invariant=(action, G)) sage: OTG1 is OTG2 True """ @@ -2922,7 +2911,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): from sage.algebras.orlik_terao import OrlikTeraoAlgebra return OrlikTeraoAlgebra(R, self, ordering) - # Copying, loading, saving + # copying, loading, saving def __reduce__(self): """ @@ -3379,13 +3368,11 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``other`` -- A matroid, - - optional parameter ``certificate`` -- Boolean. - - OUTPUT: + - ``other`` -- matroid + - ``certificate`` -- boolean (default: ``False``) - Boolean, - and, if certificate = True, a dictionary giving the isomorphism or None + OUTPUT: boolean, and, if ``certificate = True``, a dictionary giving + the isomorphism or ``None`` .. NOTE:: @@ -3428,13 +3415,11 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``other`` -- A matroid instance. + - ``other`` -- matroid - ``morphism`` -- a dictionary mapping the groundset of ``self`` to the groundset of ``other`` - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -3578,9 +3563,7 @@ cdef class BinaryMatroid(LinearMatroid): bicycle dimension of its cocycle-space, and is an invariant for binary matroids. See [Pen2012]_, [GR2001]_ for more information. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -3610,9 +3593,7 @@ cdef class BinaryMatroid(LinearMatroid): The Brown invariant of a binary matroid equals the Brown invariant of its cocycle-space. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -3634,7 +3615,7 @@ cdef class BinaryMatroid(LinearMatroid): Return the principal tripartition of the binary matroid. The principal tripartition is a partition `(F_{-1}, F_0, F_{1})` of - the ground set. A defining property is the following. It is + the groundset. A defining property is the following. It is straightforward that if the bicycle dimension of a matroid `M` is `k`, then the bicycle dimension of `M\setminus e' is one of `k-1, k, k + 1` for each element `e` of `M`. Then if `F_i` denotes the set of elements @@ -3780,10 +3761,10 @@ cdef class BinaryMatroid(LinearMatroid): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` .. NOTE:: @@ -3817,7 +3798,7 @@ cdef class BinaryMatroid(LinearMatroid): keep_initial_representation=False) # graphicness test - cpdef is_graphic(self): + cpdef bint is_graphic(self): """ Test if the binary matroid is graphic. @@ -3826,9 +3807,7 @@ cdef class BinaryMatroid(LinearMatroid): matroid is independent if and only if the corresponding subgraph is acyclic. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -3888,7 +3867,7 @@ cdef class BinaryMatroid(LinearMatroid): # now self is graphic iff there is a binary vector x so that M*x = 0 and x_0 = 1, so: return BinaryMatroid(m).corank(frozenset([0])) > 0 - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data obey the matroid axioms. @@ -3947,9 +3926,7 @@ cdef class BinaryMatroid(LinearMatroid): - ``randomized_tests`` -- Ignored. - OUTPUT: - - A Boolean. + OUTPUT: boolean ALGORITHM: @@ -4437,13 +4414,11 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``other`` -- A matroid, - - optional parameter ``certificate`` -- Boolean. + - ``other`` -- matroid + - ``certificate`` -- boolean (default: ``False``) - OUTPUT: - - Boolean, - and, if certificate = True, a dictionary giving the isomorphism or None + OUTPUT: boolean, and, if ``certificate = True``, a dictionary giving + the isomorphism or ``None`` .. NOTE:: @@ -4557,7 +4532,7 @@ cdef class TernaryMatroid(LinearMatroid): - ``(L, La, Lb, Lc)`` is the triple of lengths of the principal quadripartition. - ``(p0, ..., p5)`` counts of edges in a characteristic graph of the - matroid whose vertex set is the ground set of the matroid, + matroid whose vertex set is the groundset of the matroid, restricted to the sets in the principal quadripartition. EXAMPLES:: @@ -4579,9 +4554,7 @@ cdef class TernaryMatroid(LinearMatroid): bicycle dimension of its rowspace, and is a matroid invariant. See [Pen2012]_. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -4605,9 +4578,7 @@ cdef class TernaryMatroid(LinearMatroid): character of its cocycle-space, and is an invariant for ternary matroids. See [Pen2012]_. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: @@ -4621,9 +4592,9 @@ cdef class TernaryMatroid(LinearMatroid): cpdef _principal_quadripartition(self): r""" - Return an ordered partition of the ground set. + Return an ordered partition of the groundset. - The partition groups each element `e` of the ground set + The partition groups each element `e` of the groundset according to the bicycle dimension and the character of `M/e`, where `M` is the present matroid. @@ -4730,10 +4701,10 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` .. NOTE:: @@ -4766,7 +4737,7 @@ cdef class TernaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data obey the matroid axioms. @@ -4823,11 +4794,9 @@ cdef class TernaryMatroid(LinearMatroid): INPUT: - - ``randomized_tests`` -- Ignored. - - OUTPUT: + - ``randomized_tests`` -- ignored - A Boolean. + OUTPUT: boolean ALGORITHM: @@ -5247,7 +5216,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings sage: M._basic_representation() # needs sage.rings.finite_rings 5 x 10 QuaternaryMatrix [100001x00y] @@ -5290,7 +5259,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings sage: M._reduced_representation() # needs sage.rings.finite_rings 5 x 5 QuaternaryMatrix [1x00y] @@ -5318,7 +5287,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings sage: M._invariant() # indirect doctest # needs sage.rings.finite_rings (0, 0, 5, 5, 20, 10, 25) """ @@ -5397,7 +5366,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings sage: M._invariant() # needs sage.rings.finite_rings (0, 0, 5, 5, 20, 10, 25) """ @@ -5418,13 +5387,11 @@ cdef class QuaternaryMatroid(LinearMatroid): The bicycle dimension of a matroid equals the bicycle dimension of its rowspace, and is a matroid invariant. See [Pen2012]_. - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: - sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings sage: M.bicycle_dimension() # needs sage.rings.finite_rings 0 """ @@ -5437,7 +5404,7 @@ cdef class QuaternaryMatroid(LinearMatroid): Return the principal tripartition of the quaternary matroid. The principal tripartition is a partition `(F_{-1}, F_0, F_{1})` of - the ground set. A defining property is the following. It is + the groundset. A defining property is the following. It is straightforward that if the bicycle dimension of a matroid `M` is `k`, then the bicycle dimension of `M\setminus e' is one of `k-1, k, k + 1` for each element `e` of `M`. Then if `F_i` denotes the set of elements @@ -5490,8 +5457,8 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.catalog.Q10().delete('a') # needs sage.rings.finite_rings - sage: N = matroids.catalog.Q10().delete('b') # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10().delete('a') # needs sage.rings.finite_rings + sage: N = matroids.catalog.Q10().delete('b') # needs sage.rings.finite_rings sage: M._fast_isom_test(N) is None # needs sage.rings.finite_rings True """ @@ -5506,10 +5473,10 @@ cdef class QuaternaryMatroid(LinearMatroid): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` .. NOTE:: @@ -5526,7 +5493,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q10() # needs sage.rings.finite_rings sage: N = M._minor(contractions=set(['a']), deletions=set([])) # needs sage.rings.finite_rings sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) # needs sage.rings.finite_rings Quaternary matroid of rank 4 on 7 elements @@ -5542,7 +5509,7 @@ cdef class QuaternaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data obey the matroid axioms. @@ -5958,6 +5925,7 @@ cdef class RegularMatroid(LinearMatroid): sage: M._invariant() == O._invariant() False """ + from sage.matroids.utilities import cmp_elements_key # TODO: this currently uses Sage matrices internally. Perhaps dependence on those can be eliminated for further speed gains. if self._r_invariant is not None: return self._r_invariant @@ -5983,7 +5951,7 @@ cdef class RegularMatroid(LinearMatroid): for k in range(j): if P.get_unsafe(i, j)*P.get_unsafe(j, k)*P.get_unsafe(k, i)<0: N=N+1 - self._r_invariant = hash(tuple([tuple([(w, A[w]) for w in sorted(A)]), tuple([(w, B[w]) for w in sorted(B)]), N])) + self._r_invariant = hash(tuple([tuple([(w, A[w]) for w in sorted(A, key=cmp_elements_key)]), tuple([(w, B[w]) for w in sorted(B, key=cmp_elements_key)]), N])) return self._r_invariant cpdef _hypergraph(self): @@ -6016,6 +5984,7 @@ cdef class RegularMatroid(LinearMatroid): """ # NEW VERSION, Uses Sage'S Graph Isomorphism from sage.graphs.digraph import DiGraph + from sage.matroids.utilities import cmp_elements_key if self._r_hypergraph is not None: return (self._hypergraph_vertex_partition, self._hypergraph_tuples, self._r_hypergraph) cdef Matrix P = self._projection() @@ -6041,8 +6010,8 @@ cdef class RegularMatroid(LinearMatroid): else: B[w] = [frozenset([e, f])] E.append(frozenset([e, f])) - self._hypergraph_vertex_partition = [[str(x) for x in A[w]] for w in sorted(A)] + [['**' + str(x) for x in B[w]] for w in sorted(B)] - self._hypergraph_tuples = [(w, len(A[w])) for w in sorted(A)] + [(w, len(B[w])) for w in sorted(B)] + self._hypergraph_vertex_partition = [[str(x) for x in A[w]] for w in sorted(A, key=cmp_elements_key)] + [['**' + str(x) for x in B[w]] for w in sorted(B, key=cmp_elements_key)] + self._hypergraph_tuples = [(w, len(A[w])) for w in sorted(A, key=cmp_elements_key)] + [(w, len(B[w])) for w in sorted(B, key=cmp_elements_key)] G = DiGraph() G.add_vertices([str(x) for x in V] + ['**' + str(x) for x in E]) # Note that Sage's Graph object attempts a sort on calling G.vertices(), which means vertices have to be well-behaved. @@ -6077,13 +6046,11 @@ cdef class RegularMatroid(LinearMatroid): INPUT: - - ``other`` -- A matroid, - - optional parameter ``certificate`` -- Boolean. - - OUTPUT: + - ``other`` -- matroid + - ``certificate`` -- boolean (default: ``False``) - Boolean, - and, if certificate = True, a dictionary giving the isomorphism or None + OUTPUT: boolean, and, if ``certificate = True``, a dictionary giving + the isomorphism or ``None`` .. NOTE:: @@ -6288,20 +6255,20 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: sage: M = matroids.Wheel(3) - sage: len(M._linear_extension_chains(F=set([0, 1, 2]))) + sage: len(M._linear_extension_chains(F=frozenset([0, 1, 2]))) 7 - sage: M._linear_extension_chains(F=set()) + sage: M._linear_extension_chains(F=frozenset()) [{}] - sage: M._linear_extension_chains(F=set([1])) + sage: M._linear_extension_chains(F=frozenset([1])) [{}, {1: 1}] - sage: len(M._linear_extension_chains(F=set([0, 1]))) + sage: len(M._linear_extension_chains(F=frozenset([0, 1]))) 4 """ if fundamentals is None: fundamentals = set([1]) return LinearMatroid._linear_extension_chains(self, F, fundamentals) - cpdef is_graphic(self): + cpdef bint is_graphic(self): """ Test if the regular matroid is graphic. @@ -6310,9 +6277,7 @@ cdef class RegularMatroid(LinearMatroid): matroid is independent if and only if the corresponding subgraph is acyclic. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -6334,7 +6299,7 @@ cdef class RegularMatroid(LinearMatroid): """ return BinaryMatroid(reduced_matrix=self._reduced_representation()).is_graphic() - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data obey the matroid axioms. @@ -6342,9 +6307,7 @@ cdef class RegularMatroid(LinearMatroid): representation matrix is *totally unimodular*, i.e. if all square submatrices have determinant in `\{-1, 0, 1\}`. - OUTPUT: - - Boolean. + OUTPUT: boolean EXAMPLES:: @@ -6365,11 +6328,11 @@ cdef class RegularMatroid(LinearMatroid): # representation - def is_regular(self): + cpdef bint is_regular(self): r""" Return if ``self`` is regular. - This is trivially ``True`` for a class:`RegularMatroid`. + This is trivially ``True`` for a :class:`RegularMatroid`. EXAMPLES:: @@ -6418,9 +6381,7 @@ cdef class RegularMatroid(LinearMatroid): - ``randomized_tests`` -- Ignored. - OUTPUT: - - A Boolean. + OUTPUT: boolean ALGORITHM: @@ -6477,9 +6438,7 @@ cdef class RegularMatroid(LinearMatroid): - ``randomized_tests`` -- Ignored. - OUTPUT: - - A Boolean. + OUTPUT: boolean ALGORITHM: diff --git a/src/sage/matroids/matroid.pxd b/src/sage/matroids/matroid.pxd index e5ebe0505fa..ca197f605b9 100644 --- a/src/sage/matroids/matroid.pxd +++ b/src/sage/matroids/matroid.pxd @@ -1,4 +1,5 @@ from sage.structure.sage_object cimport SageObject +from sage.matroids.set_system cimport SetSystem cdef class Matroid(SageObject): cdef public _SageObject__custom_name @@ -7,29 +8,29 @@ cdef class Matroid(SageObject): cdef int _stored_size # virtual methods - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) # internal methods, assuming verified input - cpdef _max_independent(self, X) - cpdef _circuit(self, X) - cpdef _fundamental_circuit(self, B, e) - cpdef _closure(self, X) - cpdef _corank(self, X) - cpdef _max_coindependent(self, X) - cpdef _cocircuit(self, X) - cpdef _fundamental_cocircuit(self, B, e) - cpdef _coclosure(self, X) - cpdef _augment(self, X, Y) - - cpdef _is_independent(self, X) - cpdef _is_basis(self, X) - cpdef _is_circuit(self, X) - cpdef _is_closed(self, X) - cpdef _is_coindependent(self, X) - cpdef _is_cobasis(self, X) - cpdef _is_cocircuit(self, X) - cpdef _is_coclosed(self, X) + cpdef frozenset _max_independent(self, frozenset X) + cpdef frozenset _circuit(self, frozenset X) + cpdef frozenset _fundamental_circuit(self, frozenset B, e) + cpdef frozenset _closure(self, frozenset X) + cpdef int _corank(self, frozenset X) + cpdef frozenset _max_coindependent(self, frozenset X) + cpdef frozenset _cocircuit(self, frozenset X) + cpdef frozenset _fundamental_cocircuit(self, frozenset B, e) + cpdef frozenset _coclosure(self, frozenset X) + cpdef frozenset _augment(self, frozenset X, frozenset Y) + + cpdef bint _is_independent(self, frozenset X) + cpdef bint _is_basis(self, frozenset X) + cpdef bint _is_circuit(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) + cpdef bint _is_coindependent(self, frozenset X) + cpdef bint _is_cobasis(self, frozenset X) + cpdef bint _is_cocircuit(self, frozenset X) + cpdef bint _is_coclosed(self, frozenset X) cpdef _minor(self, contractions, deletions) cpdef _has_minor(self, N, bint certificate=*) @@ -104,30 +105,30 @@ cdef class Matroid(SageObject): cpdef is_coclosed(self, X) # verification - cpdef is_valid(self) + cpdef bint is_valid(self) # enumeration - cpdef circuits(self) - cpdef nonspanning_circuits(self) - cpdef cocircuits(self) - cpdef noncospanning_cocircuits(self) - cpdef circuit_closures(self) - cpdef nonspanning_circuit_closures(self) - cpdef bases(self) - cpdef independent_sets(self) - cpdef independent_r_sets(self, long r) - cpdef nonbases(self) - cpdef dependent_r_sets(self, long r) - cpdef _extend_flags(self, flags) - cpdef _flags(self, r) - cpdef flats(self, r) - cpdef coflats(self, r) - cpdef hyperplanes(self) - cpdef f_vector(self) - cpdef whitney_numbers(self) - cpdef whitney_numbers2(self) - cpdef broken_circuits(self, ordering=*) - cpdef no_broken_circuits_sets(self, ordering=*) + cpdef SetSystem circuits(self, k=*) + cpdef SetSystem nonspanning_circuits(self) + cpdef SetSystem cocircuits(self) + cpdef SetSystem noncospanning_cocircuits(self) + cpdef dict circuit_closures(self) + cpdef dict nonspanning_circuit_closures(self) + cpdef SetSystem bases(self) + cpdef SetSystem independent_sets(self, long k=*) + cdef SetSystem _independent_sets(self) + cpdef SetSystem nonbases(self) + cpdef SetSystem dependent_sets(self, long k) + cpdef list _extend_flags(self, list flags) + cpdef list _flags(self, long k) + cpdef SetSystem flats(self, long k) + cpdef SetSystem coflats(self, long k) + cpdef SetSystem hyperplanes(self) + cpdef list f_vector(self) + cpdef list whitney_numbers(self) + cpdef list whitney_numbers2(self) + cpdef SetSystem broken_circuits(self, ordering=*) + cpdef SetSystem no_broken_circuits_sets(self, ordering=*) # polytopes cpdef matroid_polytope(self) @@ -183,8 +184,8 @@ cdef class Matroid(SageObject): cpdef _is_3connected_CE(self, certificate=*) cpdef _is_3connected_BC(self, certificate=*) cpdef _is_3connected_BC_recursion(self, basis, fund_cocircuits) - cpdef is_paving(self) - cpdef is_sparse_paving(self) + cpdef bint is_paving(self) + cpdef bint is_sparse_paving(self) cpdef girth(self) # representability @@ -194,8 +195,8 @@ cdef class Matroid(SageObject): cpdef _local_ternary_matroid(self, basis=*) cpdef ternary_matroid(self, randomized_tests=*, verify=*) cpdef is_ternary(self, randomized_tests=*) - cpdef is_regular(self) - cpdef is_graphic(self) + cpdef bint is_regular(self) + cpdef bint is_graphic(self) # matroid k-closed cpdef is_k_closed(self, int k) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 531d8e90490..5591e14c038 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -63,9 +63,9 @@ additional functionality (e.g. linear extensions). - :meth:`circuit_closures() ` - :meth:`nonspanning_circuit_closures() ` - :meth:`bases() ` - - :meth:`independent_r_sets() ` + - :meth:`independent_sets() ` - :meth:`nonbases() ` - - :meth:`dependent_r_sets() ` + - :meth:`dependent_sets() ` - :meth:`flats() ` - :meth:`coflats() ` - :meth:`hyperplanes() ` @@ -212,16 +212,16 @@ in which the partition is specified as a list of lists:: ....: def _rank(self, X): ....: X2 = set(X) ....: used_indices = set() - ....: rk = 0 + ....: r = 0 ....: while X2: ....: e = X2.pop() ....: for i in range(len(self.partition)): ....: if e in self.partition[i]: ....: if i not in used_indices: ....: used_indices.add(i) - ....: rk = rk + 1 + ....: r = r + 1 ....: break - ....: return rk + ....: return r ....: sage: M = PartitionMatroid([[1, 2], [3, 4, 5], [6, 7]]) sage: M.full_rank() @@ -348,7 +348,7 @@ from itertools import combinations, product from sage.matrix.constructor import matrix from sage.misc.lazy_import import LazyImport from sage.misc.prandom import shuffle -from sage.misc.superseded import deprecation +from sage.misc.superseded import deprecation, deprecated_function_alias from sage.rings.integer_ring import ZZ from sage.structure.richcmp cimport rich_to_bool, richcmp from sage.structure.sage_object cimport SageObject @@ -393,16 +393,16 @@ cdef class Matroid(SageObject): ....: def _rank(self, X): ....: X2 = set(X) ....: used_indices = set() - ....: rk = 0 + ....: r = 0 ....: while X2: ....: e = X2.pop() ....: for i in range(len(self.partition)): ....: if e in self.partition[i]: ....: if i not in used_indices: ....: used_indices.add(i) - ....: rk = rk + 1 + ....: r = r + 1 ....: break - ....: return rk + ....: return r ....: sage: M = PartitionMatroid([[1, 2], [3, 4, 5], [6, 7]]) sage: M.full_rank() @@ -469,13 +469,13 @@ cdef class Matroid(SageObject): # virtual methods - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. The groundset is the set of elements that comprise the matroid. - OUTPUT: a set + OUTPUT: :class:`frozenset` .. NOTE:: @@ -488,11 +488,11 @@ cdef class Matroid(SageObject): sage: M.groundset() Traceback (most recent call last): ... - NotImplementedError: subclasses need to implement this. + NotImplementedError: subclasses need to implement this """ - raise NotImplementedError("subclasses need to implement this.") + raise NotImplementedError("subclasses need to implement this") - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): r""" Return the rank of a set ``X``. @@ -501,9 +501,9 @@ cdef class Matroid(SageObject): INPUT: - - ``X`` -- an object with Python's ``frozenset`` interface. + - ``X`` -- an object with Python's ``frozenset`` interface - OUTPUT: an integer + OUTPUT: integer .. NOTE:: @@ -512,12 +512,11 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = sage.matroids.matroid.Matroid() - sage: M._rank([0, 1, 2]) - Traceback (most recent call last): + sage: M._rank(frozenset([0, 1, 2])) + NotImplementedError: subclasses need to implement this ... - NotImplementedError: subclasses need to implement this. """ - raise NotImplementedError("subclasses need to implement this.") + raise NotImplementedError("subclasses need to implement this") # copying @@ -532,6 +531,7 @@ cdef class Matroid(SageObject): ....: BasisMatroid(matroids.catalog.Vamos()), ....: CircuitsMatroid(matroids.catalog.Vamos()), ....: CircuitClosuresMatroid(matroids.catalog.Vamos()), + ....: FlatsMatroid(matroids.catalog.Vamos()), ....: Matroid(groundset=range(10), rank_function=lambda X: min(len(X), 4)), ....: Matroid(Matrix(GF(7), [[1,0,0,1,1],[0,1,0,1,2],[0,0,1,1,3]])), ....: Matroid(Matrix(GF(2), [[1,0,0,1,1],[0,1,0,1,2],[0,0,1,1,3]])), @@ -577,6 +577,7 @@ cdef class Matroid(SageObject): ....: BasisMatroid(matroids.catalog.Vamos()), ....: CircuitsMatroid(matroids.catalog.Vamos()), ....: CircuitClosuresMatroid(matroids.catalog.Vamos()), + ....: FlatsMatroid(matroids.catalog.Vamos()), ....: Matroid(groundset=range(10), rank_function=lambda X: min(len(X), 4)), ....: Matroid(Matrix(GF(7), [[1,0,0,1,1],[0,1,0,1,2],[0,0,1,1,3]])), ....: Matroid(Matrix(GF(2), [[1,0,0,1,1],[0,1,0,1,2],[0,0,1,1,3]])), @@ -616,44 +617,44 @@ cdef class Matroid(SageObject): # for better efficiency, its best to override the following methods in # each derived class - cpdef _max_independent(self, X): + cpdef frozenset _max_independent(self, frozenset X): """ Compute a maximal independent subset. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: a subset of the groundset as a :class:`frozenset` EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: X = M._max_independent(set(['a', 'c', 'd', 'e', 'f'])) + sage: X = M._max_independent(frozenset(['a', 'c', 'd', 'e', 'f'])) sage: M.is_independent(X) True sage: all(M.is_dependent(X.union([y])) for y in M.groundset() if y not in X) True """ - res = set([]) - r = 0 + cdef list res = [] + cdef int r = 0 for e in X: - res.add(e) + res.append(e) if self._rank(res) > r: r += 1 else: - res.discard(e) + res.pop() return frozenset(res) - cpdef _circuit(self, X): + cpdef frozenset _circuit(self, frozenset X): """ Return a minimal dependent subset. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -664,27 +665,27 @@ cdef class Matroid(SageObject): sage: M = matroids.catalog.Vamos() sage: sorted(sage.matroids.matroid.Matroid._circuit(M, - ....: set(['a', 'c', 'd', 'e', 'f']))) + ....: frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] sage: sorted(sage.matroids.matroid.Matroid._circuit(M, - ....: set(['a', 'c', 'd']))) + ....: frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no circuit in independent set. """ - Z = set(X) + cdef set Z = set(X) if self._is_independent(X): raise ValueError("no circuit in independent set.") - l = len(X) - 1 + cdef int l = len(X) - 1 for x in X: Z.discard(x) - if self._rank(Z) == l: + if self._rank(frozenset(Z)) == l: Z.add(x) else: l -= 1 return frozenset(Z) - cpdef _fundamental_circuit(self, B, e): + cpdef frozenset _fundamental_circuit(self, frozenset B, e): r""" Return the `B`-fundamental circuit using `e`. @@ -705,89 +706,89 @@ cdef class Matroid(SageObject): """ return self._circuit(B.union([e])) - cpdef _closure(self, X): + cpdef frozenset _closure(self, frozenset X): """ Return the closure of a set. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: a subset of the groundset as a :class:`frozenset` EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: sorted(M._closure(set(['a', 'b', 'c']))) + sage: sorted(M._closure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] """ - X = set(X) - Y = self.groundset().difference(X) - r = self._rank(X) + cdef list XX = list(X) + cdef frozenset Y = self.groundset().difference(frozenset(X)) + cdef int r = self._rank(frozenset(X)) for y in Y: - X.add(y) - if self._rank(X) > r: - X.discard(y) - return frozenset(X) + XX.append(y) + if self._rank(frozenset(XX)) > r: + XX.pop() + return frozenset(XX) - cpdef _corank(self, X): + cpdef int _corank(self, frozenset X): """ Return the corank of a set. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._corank(set(['a', 'e', 'g', 'd', 'h'])) + sage: M._corank(frozenset(['a', 'e', 'g', 'd', 'h'])) 4 """ return len(X) + self._rank(self.groundset().difference(X)) - self.full_rank() - cpdef _max_coindependent(self, X): + cpdef frozenset _max_coindependent(self, frozenset X): """ Compute a maximal coindependent subset. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: a subset of the groundset as a :class:`frozenset` EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: X = M._max_coindependent(set(['a', 'c', 'd', 'e', 'f'])) + sage: X = M._max_coindependent(frozenset(['a', 'c', 'd', 'e', 'f'])) sage: M.is_coindependent(X) True sage: all(M.is_codependent(X.union([y])) for y in M.groundset() if y not in X) True """ - res = set([]) - r = 0 + cdef set res = set() + cdef int r = 0 for e in X: res.add(e) - if self._corank(res) > r: + if self._corank(frozenset(res)) > r: r += 1 else: res.discard(e) return frozenset(res) - cpdef _cocircuit(self, X): + cpdef frozenset _cocircuit(self, frozenset X): """ Return a minimal codependent subset. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -798,27 +799,27 @@ cdef class Matroid(SageObject): sage: M = matroids.catalog.Vamos() sage: sorted(sage.matroids.matroid.Matroid._cocircuit(M, - ....: set(['a', 'c', 'd', 'e', 'f']))) + ....: frozenset(['a', 'c', 'd', 'e', 'f']))) ['c', 'd', 'e', 'f'] sage: sorted(sage.matroids.matroid.Matroid._cocircuit(M, - ....: set(['a', 'c', 'd']))) + ....: frozenset(['a', 'c', 'd']))) Traceback (most recent call last): ... ValueError: no cocircuit in coindependent set. """ - Z = set(X) + cdef set Z = set(X) if self._is_coindependent(X): raise ValueError("no cocircuit in coindependent set.") - l = len(X) - 1 + cdef int l = len(X) - 1 for x in X: Z.discard(x) - if self._corank(Z) == l: + if self._corank(frozenset(Z)) == l: Z.add(x) else: l -= 1 return frozenset(Z) - cpdef _fundamental_cocircuit(self, B, e): + cpdef frozenset _fundamental_cocircuit(self, frozenset B, e): r""" Return the `B`-fundamental circuit using `e`. @@ -834,38 +835,38 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: sorted(M._fundamental_cocircuit('abch', 'c')) + sage: sorted(M._fundamental_cocircuit(frozenset('abch'), 'c')) ['c', 'd', 'e', 'f'] """ return self._cocircuit(self.groundset().difference(B).union([e])) - cpdef _coclosure(self, X): + cpdef frozenset _coclosure(self, frozenset X): """ Return the coclosure of a set. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: a subset of the groundset as a :class:`frozenset` EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: sorted(M._coclosure(set(['a', 'b', 'c']))) + sage: sorted(M._coclosure(frozenset(['a', 'b', 'c']))) ['a', 'b', 'c', 'd'] """ - X = set(X) - Y = self.groundset().difference(X) - r = self._corank(X) + cdef set XX = set(X) + cdef frozenset Y = self.groundset().difference(X) + cdef int r = self._corank(X) for y in Y: - X.add(y) - if self._corank(X) > r: - X.discard(y) - return frozenset(X) + XX.add(y) + if self._corank(frozenset(XX)) > r: + XX.discard(y) + return frozenset(XX) - cpdef _augment(self, X, Y): + cpdef frozenset _augment(self, frozenset X, frozenset Y): r""" Return a maximal subset `I` of `Y` such that `r(X + I)=r(X) + r(I)`. @@ -874,9 +875,9 @@ cdef class Matroid(SageObject): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. - - ``Y`` -- An object with Python's ``frozenset`` interface containing + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` + - ``Y`` -- an object with Python's ``frozenset`` interface containing a subset of ``self.groundset()``, and disjoint from ``X``. OUTPUT: a subset of the groundset as a :class:`frozenset` @@ -884,54 +885,54 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: X = set(['a']); Y = set(['e', 'f', 'g', 'h']) + sage: X = frozenset(['a']); Y = frozenset(['e', 'f', 'g', 'h']) sage: Z = M._augment(X, Y) sage: M.is_independent(Z.union(X)) True sage: all(M.is_dependent(Z.union([y])) for y in Y if y not in Z) True """ - X = set(X) - res = set([]) - r = self._rank(X) + cdef set XX = set(X) + cdef set res = set([]) + cdef int r = self._rank(frozenset(X)) for e in Y: - X.add(e) - if self.rank(X) > r: + XX.add(e) + if self._rank(frozenset(XX)) > r: r += 1 res.add(e) return frozenset(res) # override the following methods for even better efficiency - cpdef _is_independent(self, X): + cpdef bint _is_independent(self, frozenset X): """ Test if input is independent. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_independent(set(['a', 'b', 'c'])) + sage: M._is_independent(frozenset(['a', 'b', 'c'])) True - sage: M._is_independent(set(['a', 'b', 'c', 'd'])) + sage: M._is_independent(frozenset(['a', 'b', 'c', 'd'])) False """ return len(X) == self._rank(X) - cpdef _is_basis(self, X): + cpdef bint _is_basis(self, frozenset X): """ Test if input is a basis. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` .. WARNING:: @@ -944,38 +945,38 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_basis(set(['a', 'b', 'c', 'e'])) + sage: M._is_basis(frozenset(['a', 'b', 'c', 'e'])) True - sage: M._is_basis(set(['a', 'b', 'c', 'd'])) + sage: M._is_basis(frozenset(['a', 'b', 'c', 'd'])) False If ``X`` does not have the right size, behavior can become unpredictable:: - sage: M._is_basis(set(['a', 'b', 'c'])) + sage: M._is_basis(frozenset(['a', 'b', 'c'])) True """ return self._is_independent(X) - cpdef _is_circuit(self, X): + cpdef bint _is_circuit(self, frozenset X): """ Test if input is a circuit. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_circuit(set(['a', 'b', 'c', 'd'])) + sage: M._is_circuit(frozenset(['a', 'b', 'c', 'd'])) True - sage: M._is_circuit(set(['a', 'b', 'c', 'e'])) + sage: M._is_circuit(frozenset(['a', 'b', 'c', 'e'])) False - sage: M._is_circuit(set(['a', 'b', 'c', 'd', 'e'])) + sage: M._is_circuit(frozenset(['a', 'b', 'c', 'd', 'e'])) False """ l = len(X) - 1 @@ -989,64 +990,64 @@ cdef class Matroid(SageObject): Z.add(x) return True - cpdef _is_closed(self, X): + cpdef bint _is_closed(self, frozenset X): """ Test if input is a closed set. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_closed(set(['a', 'b', 'c', 'd'])) + sage: M._is_closed(frozenset(['a', 'b', 'c', 'd'])) True - sage: M._is_closed(set(['a', 'b', 'c', 'e'])) + sage: M._is_closed(frozenset(['a', 'b', 'c', 'e'])) False """ - X = set(X) - Y = self.groundset().difference(X) - r = self._rank(X) + cdef set XX = set(X) + cdef frozenset Y = self.groundset().difference(X) + cdef int r = self._rank(frozenset(X)) for y in Y: - X.add(y) - if self._rank(frozenset(X)) == r: + XX.add(y) + if self._rank(frozenset(XX)) == r: return False - X.discard(y) + XX.discard(y) return True - cpdef _is_coindependent(self, X): + cpdef bint _is_coindependent(self, frozenset X): """ Test if input is coindependent. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_coindependent(set(['a', 'b', 'c'])) + sage: M._is_coindependent(frozenset(['a', 'b', 'c'])) True - sage: M._is_coindependent(set(['a', 'b', 'c', 'd'])) + sage: M._is_coindependent(frozenset(['a', 'b', 'c', 'd'])) False """ return self._corank(X) == len(X) - cpdef _is_cobasis(self, X): + cpdef bint _is_cobasis(self, frozenset X): """ Test if input is a cobasis. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean @@ -1058,34 +1059,34 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_cobasis(set(['a', 'b', 'c', 'e'])) + sage: M._is_cobasis(frozenset(['a', 'b', 'c', 'e'])) True - sage: M._is_cobasis(set(['a', 'b', 'c', 'd'])) + sage: M._is_cobasis(frozenset(['a', 'b', 'c', 'd'])) False - sage: M._is_cobasis(set(['a', 'b', 'c'])) + sage: M._is_cobasis(frozenset(['a', 'b', 'c'])) False """ return self._is_basis(self.groundset().difference(X)) - cpdef _is_cocircuit(self, X): + cpdef bint _is_cocircuit(self, frozenset X): """ Test if input is a cocircuit. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_cocircuit(set(['a', 'b', 'c', 'd'])) + sage: M._is_cocircuit(frozenset(['a', 'b', 'c', 'd'])) True - sage: M._is_cocircuit(set(['a', 'b', 'c', 'e'])) + sage: M._is_cocircuit(frozenset(['a', 'b', 'c', 'e'])) False - sage: M._is_cocircuit(set(['a', 'b', 'c', 'd', 'e'])) + sage: M._is_cocircuit(frozenset(['a', 'b', 'c', 'd', 'e'])) False """ l = len(X) - 1 @@ -1099,33 +1100,33 @@ cdef class Matroid(SageObject): Z.add(x) return True - cpdef _is_coclosed(self, X): + cpdef bint _is_coclosed(self, frozenset X): """ Test if input is a coclosed set. INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: boolean EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M._is_coclosed(set(['a', 'b', 'c', 'd'])) + sage: M._is_coclosed(frozenset(['a', 'b', 'c', 'd'])) True - sage: M._is_coclosed(set(['a', 'b', 'c', 'e'])) + sage: M._is_coclosed(frozenset(['a', 'b', 'c', 'e'])) False """ - X = set(X) - Y = self.groundset().difference(X) - r = self._corank(X) + cdef set XX = set(X) + cdef frozenset Y = self.groundset().difference(X) + cdef int r = self._corank(X) for y in Y: - X.add(y) - if self._corank(frozenset(X)) == r: + XX.add(y) + if self._corank(frozenset(XX)) == r: return False - X.discard(y) + XX.discard(y) return True cpdef _minor(self, contractions, deletions): @@ -1134,10 +1135,10 @@ cdef class Matroid(SageObject): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` .. NOTE:: @@ -1209,8 +1210,8 @@ cdef class Matroid(SageObject): if certificate: return False, None return False - YY = self.dual().independent_r_sets(cd) - for X in self.independent_r_sets_iterator(rd): + YY = self.dual().independent_sets(cd) + for X in self.independent_sets_iterator(rd): for Y in YY: if X.isdisjoint(Y): if N._is_isomorphic(self._minor(contractions=X, deletions=Y)): @@ -1232,7 +1233,7 @@ cdef class Matroid(SageObject): - ``F`` -- a subset of the groundset, assumed to be a closed set of rank `r(M) - 2`. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1313,7 +1314,7 @@ cdef class Matroid(SageObject): """ Return the size of the groundset. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1398,7 +1399,7 @@ cdef class Matroid(SageObject): - ``X`` -- (default: the groundset) a subset (or any iterable) of the groundset - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1423,7 +1424,7 @@ cdef class Matroid(SageObject): The *rank* of the matroid is the size of the largest independent subset of the groundset. - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -1472,7 +1473,7 @@ cdef class Matroid(SageObject): - ``X`` -- a subset (or any iterable) of the groundset - OUTPUT: a subset of ``X`` + OUTPUT: subset of ``X`` EXAMPLES:: @@ -1574,7 +1575,7 @@ cdef class Matroid(SageObject): - ``X`` -- a subset (or any iterable) of the groundset - OUTPUT: a superset of ``X`` + OUTPUT: superset of ``X`` EXAMPLES:: @@ -1634,7 +1635,7 @@ cdef class Matroid(SageObject): cur = len(S) cl = frozenset([]) for T in combinations(S, min(k, cur)): - cl = cl.union(self._closure(set(T))) + cl = cl.union(self._closure(frozenset(T))) S = cl return S @@ -1688,7 +1689,7 @@ cdef class Matroid(SageObject): - ``X`` -- (default: the groundset) a subset (or any iterable) of the groundset - OUTPUT: an integer + OUTPUT: integer .. SEEALSO:: @@ -1716,7 +1717,7 @@ cdef class Matroid(SageObject): The *corank* of the matroid equals the rank of the dual matroid. It is given by ``M.size() - M.full_rank()``. - OUTPUT: an integer + OUTPUT: integer .. SEEALSO:: @@ -1811,7 +1812,7 @@ cdef class Matroid(SageObject): - ``X`` -- a subset (or any iterable) of the groundset - OUTPUT: a superset of ``X`` + OUTPUT: superset of ``X`` .. SEEALSO:: @@ -1930,7 +1931,7 @@ cdef class Matroid(SageObject): sage: (M / ['a', 'b']).loops() frozenset({'f'}) """ - return self._closure(set()) + return self._closure(frozenset()) cpdef is_independent(self, X): r""" @@ -2140,7 +2141,7 @@ cdef class Matroid(SageObject): sage: (M.delete(['a', 'b'])).coloops() frozenset({'f'}) """ - return self._coclosure(set()) + return self._coclosure(frozenset()) cpdef is_coindependent(self, X): r""" @@ -2304,7 +2305,7 @@ cdef class Matroid(SageObject): # verification - cpdef is_valid(self): + cpdef bint is_valid(self): r""" Test if the data obey the matroid axioms. @@ -2342,31 +2343,37 @@ cdef class Matroid(SageObject): sage: M.is_valid() False """ - E = list(self.groundset()) + cdef int i, j, rX, rY + cdef frozenset X, Y, E = self.groundset() for i in range(len(E) + 1): - for X in combinations(E, i): - XX = frozenset(X) - rX = self._rank(XX) + for Xt in combinations(E, i): + X = frozenset(Xt) + rX = self._rank(X) if rX > i or rX < 0: return False for j in range(i, len(E) + 1): - for Y in combinations(E, j): - YY = frozenset(Y) - rY = self._rank(YY) - if XX.issubset(YY) and rX > rY: + for Yt in combinations(E, j): + Y = frozenset(Yt) + rY = self._rank(Y) + if X.issubset(Y) and rX > rY: return False - if (self._rank(XX.union(YY)) + - self._rank(XX.intersection(YY)) > rX + rY): + if (self._rank(X.union(Y)) + + self._rank(X.intersection(Y)) > rX + rY): return False return True # enumeration - cpdef circuits(self): + cpdef SetSystem circuits(self, k=None): """ Return the circuits of the matroid. - OUTPUT: a :class:`SetSystem` + INPUT: + + - ``k`` -- integer (optional); if provided, return only circuits of + length `k` + + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -2382,14 +2389,22 @@ cdef class Matroid(SageObject): ['b', 'd', 'f', 'g'], ['b', 'e', 'g'], ['c', 'd', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] """ - C = set() - B_ext = set() - for B in self.bases_iterator(): - for e in B ^ self.groundset(): - B_ext.add(B | set([e])) - for S in B_ext: - C.add(self._circuit(S)) - return SetSystem(self.groundset(), C) + cdef frozenset E = self.groundset() + cdef set C_set = set() + cdef set B_ext = set() + cdef frozenset X + if k is None: + for B in self.bases_iterator(): + for e in B ^ E: + B_ext.add(B | {e}) + for X in B_ext: + C_set.add(self._circuit(X)) + else: + for Xt in combinations(E, k): + X = frozenset(Xt) + if self._is_circuit(X): + C_set.add(X) + return SetSystem(E, C_set) def circuits_iterator(self, k=None): """ @@ -2409,29 +2424,30 @@ cdef class Matroid(SageObject): ['b', 'd', 'f', 'g'], ['b', 'e', 'g'], ['c', 'd', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] """ - rk = self.rank() + cdef int start, stop, j, r = self.rank() + cdef frozenset X if k is None: start = 0 - stop = rk + 2 + stop = r + 2 else: - if k >= rk + 2: + if k >= r + 2: return start = k stop = k + 1 for j in range(start, stop): - for X in combinations(self.groundset(), j): - X = frozenset(X) + for Xt in combinations(self.groundset(), j): + X = frozenset(Xt) if self._is_circuit(X): yield X - cpdef nonspanning_circuits(self): + cpdef SetSystem nonspanning_circuits(self): """ Return the nonspanning circuits of the matroid. A *nonspanning circuit* is a circuit whose rank is strictly smaller than the rank of the matroid. - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -2446,12 +2462,11 @@ cdef class Matroid(SageObject): ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] """ - cdef SetSystem C - C = SetSystem(self.groundset()) + cdef SetSystem NSC = SetSystem(self.groundset()) for N in self.nonbases_iterator(): if self._rank(N) == self.full_rank() - 1: - C.append(self._circuit(N)) - return C + NSC.append(self._circuit(N)) + return NSC def nonspanning_circuits_iterator(self): """ @@ -2473,17 +2488,19 @@ cdef class Matroid(SageObject): ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] """ + cdef int k + cdef frozenset X for k in range(self.rank() + 1): - for X in combinations(self.groundset(), k): - X = frozenset(X) + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) if self._is_circuit(X): yield X - cpdef cocircuits(self): + cpdef SetSystem cocircuits(self): """ Return the cocircuits of the matroid. - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -2500,16 +2517,40 @@ cdef class Matroid(SageObject): C = set() for B in self.bases_iterator(): C.update([self._cocircuit(self.groundset().difference(B).union(set([e]))) for e in B]) - return list(C) + return SetSystem(self.groundset(), C) + + def cocircuits_iterator(self): + """ + Return an iterator over the cocircuits of the matroid. + + .. SEEALSO:: + + :meth:`M.cocircuit() ` + + EXAMPLES:: + + sage: M = matroids.catalog.Fano() + sage: sorted([sorted(C) for C in M.cocircuits_iterator()]) + [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], + ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], ['b', 'd', 'f', 'g'], + ['c', 'd', 'e', 'g']] + """ + cdef int n = len(self.groundset()) + cdef int k, r = self.rank() + for k in range(0, n - r + 2): + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) + if self._is_cocircuit(X): + yield X - cpdef noncospanning_cocircuits(self): + cpdef SetSystem noncospanning_cocircuits(self): """ Return the noncospanning cocircuits of the matroid. A *noncospanning cocircuit* is a cocircuit whose corank is strictly smaller than the corank of the matroid. - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -2526,7 +2567,7 @@ cdef class Matroid(SageObject): """ return self.dual().nonspanning_circuits() - cpdef circuit_closures(self): + cpdef dict circuit_closures(self): """ Return the closures of circuits of the matroid. @@ -2560,7 +2601,7 @@ cdef class Matroid(SageObject): CC[len(C) - 1].add(self.closure(C)) return {r: CC[r] for r in range(self.rank() + 1) if CC[r]} - cpdef nonspanning_circuit_closures(self): + cpdef dict nonspanning_circuit_closures(self): """ Return the closures of nonspanning circuits of the matroid. @@ -2591,14 +2632,14 @@ cdef class Matroid(SageObject): CC[len(C) - 1].add(self.closure(C)) return {r: CC[r] for r in range(self.rank() + 1) if CC[r]} - cpdef nonbases(self): + cpdef SetSystem nonbases(self): r""" Return the nonbases of the matroid. A *nonbasis* is a set with cardinality ``self.full_rank()`` that is not a basis. - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -2616,12 +2657,7 @@ cdef class Matroid(SageObject): Test all subsets of the groundset of cardinality ``self.full_rank()`` """ - cdef SetSystem res - res = SetSystem(self.groundset()) - for X in combinations(self.groundset(), self.full_rank()): - if self._rank(X) < len(X): - res.append(X) - return res + return self.dependent_sets(self.full_rank()) def nonbases_iterator(self): r""" @@ -2646,74 +2682,79 @@ cdef class Matroid(SageObject): sage: [sorted(X) for X in matroids.catalog.P6().nonbases_iterator()] [['a', 'b', 'c']] """ - for X in combinations(self.groundset(), self.full_rank()): - if self._rank(X) < len(X): - yield frozenset(X) + cdef frozenset X + for Xt in combinations(self.groundset(), self.full_rank()): + X = frozenset(Xt) + if not self._is_independent(X): + yield X + + dependent_r_sets = deprecated_function_alias(38057, dependent_sets) - cpdef dependent_r_sets(self, long r): + cpdef SetSystem dependent_sets(self, long k): r""" - Return the list of dependent subsets of fixed size. + Return the dependent sets of fixed size. INPUT: - - ``r`` -- a nonnegative integer + - ``k`` -- integer EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: M.dependent_r_sets(3) + sage: M.dependent_sets(3) SetSystem of 0 sets over 8 elements sage: sorted([sorted(X) for X in - ....: matroids.catalog.Vamos().dependent_r_sets(4)]) + ....: matroids.catalog.Vamos().dependent_sets(4)]) [['a', 'b', 'c', 'd'], ['a', 'b', 'e', 'f'], ['a', 'b', 'g', 'h'], ['c', 'd', 'e', 'f'], ['e', 'f', 'g', 'h']] ALGORITHM: - Test all subsets of the groundset of cardinality ``r`` + Test all subsets of the groundset of cardinality `k`. """ - cdef set D = set() + cdef SetSystem D_k = SetSystem(self.groundset()) cdef frozenset X - for XX in combinations(self.groundset(), r): - X = frozenset(XX) + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) if not self._is_independent(X): - D.add(X) - return SetSystem(self.groundset(), D) + D_k.append(X) + return D_k - def dependent_r_sets_iterator(self, long r): + def dependent_sets_iterator(self, long k): r""" - Return an iterator over the dependent subsets of fixed size. + Return an iterator over the dependent sets of fixed size. INPUT: - - ``r`` -- a nonnegative integer + - ``k`` -- integer ALGORITHM: - Test all subsets of the groundset of cardinality ``r``. + Test all subsets of the groundset of cardinality `k`. EXAMPLES:: sage: M = matroids.catalog.Vamos() - sage: list(M.dependent_r_sets_iterator(3)) + sage: list(M.dependent_sets_iterator(3)) [] sage: sorted([sorted(X) for X in - ....: matroids.catalog.Vamos().dependent_r_sets_iterator(4)]) + ....: matroids.catalog.Vamos().dependent_sets_iterator(4)]) [['a', 'b', 'c', 'd'], ['a', 'b', 'e', 'f'], ['a', 'b', 'g', 'h'], ['c', 'd', 'e', 'f'], ['e', 'f', 'g', 'h']] """ - for X in combinations(self.groundset(), r): - X = frozenset(X) - if self._rank(X) < len(X): + cdef frozenset X + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) + if not self._is_independent(X): yield X - cpdef bases(self): + cpdef SetSystem bases(self): r""" Return the bases of the matroid. A *basis* is a maximal independent set. - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` EXAMPLES:: @@ -2727,14 +2768,9 @@ cdef class Matroid(SageObject): .. SEEALSO:: - :meth:`M.independent_r_sets() ` + :meth:`M.independent_sets() ` """ - cdef SetSystem res - res = SetSystem(self.groundset()) - for X in combinations(self.groundset(), self.full_rank()): - if self._rank(frozenset(X)) == len(X): - res.append(X) - return res + return self.independent_sets(self.full_rank()) def bases_iterator(self): r""" @@ -2754,15 +2790,24 @@ cdef class Matroid(SageObject): .. SEEALSO:: - :meth:`M.independent_r_sets() ` + :meth:`M.independent_sets_iterator() ` """ - for X in combinations(self.groundset(), self.full_rank()): - if self._rank(frozenset(X)) == len(X): - yield frozenset(X) + cdef frozenset X + for Xt in combinations(self.groundset(), self.full_rank()): + X = frozenset(Xt) + if self._is_independent(X): + yield X - cpdef independent_sets(self): + cpdef SetSystem independent_sets(self, long k=-1): r""" - Return the list of independent subsets of the matroid. + Return the independent sets of the matroid. + + INPUT: + + - ``k`` -- integer (optional); if specified, return the size-`k` + independent sets of the matroid + + OUTPUT: :class:`SetSystem` EXAMPLES:: @@ -2770,143 +2815,116 @@ cdef class Matroid(SageObject): sage: I = M.independent_sets() sage: len(I) 121 + sage: M.independent_sets(4) + SetSystem of 0 sets over 9 elements + sage: S = M.independent_sets(3); S + SetSystem of 75 sets over 9 elements + sage: frozenset({'a', 'c', 'e'}) in S + True .. SEEALSO:: - :meth:`M.independent_r_sets() ` + :meth:`M.bases() ` """ - cdef int r - cdef int full_rank = self.full_rank() - cdef list T = [set() for r in range(full_rank)] - cdef list I = [frozenset()] * (full_rank+1) - r = 0 - - res = [frozenset()] - T[0] = set(self.groundset()) - self.closure([]) - while r >= 0: - if r + 1 == full_rank: - for x in T[r]: - I[r+1] = I[r].union([x]) - res.append(I[r+1]) - T[r] = set() - r -= 1 - elif T[r]: - I[r+1] = I[r].union([T[r].pop()]) - res.append(I[r+1]) - T[r+1] = T[r] - self._closure(I[r+1]) - r += 1 - else: - r -= 1 - return res + if k == -1: # all independent sets + return self._independent_sets() - def independent_sets_iterator(self): - r""" - Return an iterator over the independent subsets of the matroid. - - EXAMPLES:: - - sage: M = matroids.catalog.Pappus() - sage: I = list(M.independent_sets_iterator()) - sage: len(I) - 121 - - .. SEEALSO:: + # independent k-sets + cdef SetSystem I_k = SetSystem(self.groundset()) + cdef frozenset X + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) + if self._is_independent(X): + I_k.append(X) + return I_k - :meth:`M.independent_r_sets() ` + cdef SetSystem _independent_sets(self): + """ + Return all independent sets of the matroid. """ cdef int r cdef int full_rank = self.full_rank() cdef list T = [set() for r in range(full_rank)] cdef list I = [frozenset()] * (full_rank+1) r = 0 - - yield frozenset() + res = [frozenset()] T[0] = set(self.groundset()) - self.closure([]) while r >= 0: if r + 1 == full_rank: for x in T[r]: I[r+1] = I[r].union([x]) - yield I[r+1] + res.append(I[r+1]) T[r] = set() r -= 1 elif T[r]: I[r+1] = I[r].union([T[r].pop()]) - yield I[r+1] + res.append(I[r+1]) T[r+1] = T[r] - self._closure(I[r+1]) r += 1 else: r -= 1 + return SetSystem(self.groundset(), res) - cpdef independent_r_sets(self, long r): + def independent_sets_iterator(self, k=None): r""" - Return the list of size-``r`` independent subsets of the matroid. + Return an iterator over the independent sets of the matroid. INPUT: - - ``r`` -- a nonnegative integer - - ALGORITHM: - - Test all subsets of the groundset of cardinality ``r``. + - ``k`` -- integer (optional); if specified, return an iterator over + the size-`k` independent sets of the matroid EXAMPLES:: sage: M = matroids.catalog.Pappus() - sage: M.independent_r_sets(4) - SetSystem of 0 sets over 9 elements - sage: S = M.independent_r_sets(3); S - SetSystem of 75 sets over 9 elements - sage: frozenset({'a', 'c', 'e'}) in S - True - - .. SEEALSO:: - - :meth:`M.independent_sets() ` - :meth:`M.bases() ` - """ - cdef set I = set() - cdef frozenset X - for XX in combinations(self.groundset(), r): - X = frozenset(XX) - if self._is_independent(X): - I.add(X) - return SetSystem(self.groundset(), I) - - def independent_r_sets_iterator(self, r): - r""" - Return an iterator over the size-``r`` independent subsets of the - matroid. - - INPUT: - - - ``r`` -- a nonnegative integer - - EXAMPLES:: - + sage: I = list(M.independent_sets_iterator()) + sage: len(I) + 121 sage: M = matroids.catalog.Pappus() - sage: list(M.independent_r_sets_iterator(4)) + sage: list(M.independent_sets_iterator(4)) [] - sage: S = list(M.independent_r_sets_iterator(3)) + sage: S = list(M.independent_sets_iterator(3)) sage: len(S) 75 sage: frozenset({'a', 'c', 'e'}) in S True - ALGORITHM: - - Test all subsets of the groundset of cardinality ``r`` - .. SEEALSO:: - :meth:`M.independent_sets() ` - :meth:`M.bases() ` + :meth:`M.bases_iterator() ` """ - for X in combinations(self.groundset(), r): - X = frozenset(X) - if self._rank(X) == len(X): - yield X + cdef int r + cdef int full_rank = self.full_rank() + cdef list T = [set() for r in range(full_rank)] + cdef list I = [frozenset()] * (full_rank+1) + cdef frozenset X + if k is None: + r = 0 + yield frozenset() + T[0] = set(self.groundset()) - self.closure([]) + while r >= 0: + if r + 1 == full_rank: + for x in T[r]: + I[r+1] = I[r].union([x]) + yield I[r+1] + T[r] = set() + r -= 1 + elif T[r]: + I[r+1] = I[r].union([T[r].pop()]) + yield I[r+1] + T[r+1] = T[r] - self._closure(I[r+1]) + r += 1 + else: + r -= 1 + else: + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) + if self._rank(X) == len(X): + yield X - cpdef _extend_flags(self, flags): + independent_r_sets = deprecated_function_alias(38057, independent_sets) + + cpdef list _extend_flags(self, list flags): r""" Recursion for the ``self._flags(r)`` method. @@ -2917,14 +2935,14 @@ cdef class Matroid(SageObject): sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) True """ - newflags = [] + cdef list newflags = [] for [F, B, X] in flags: while X: x = min(X) # TODO: Alert: this sort of thing will break in # Python 3, I think. --SvZ newbase = B | set([x]) - newflat = self._closure(newbase) + newflat = self._closure(frozenset(newbase)) newX = X - newflat if max(newbase) == x: if min(newflat - F) == x: @@ -2932,20 +2950,20 @@ cdef class Matroid(SageObject): X = newX return newflags - cpdef _flags(self, r): + cpdef list _flags(self, long k): r""" - Compute rank-``r`` flats, with extra information for more speed. + Compute the rank-`k` flats, with extra information for more speed. Used in the :meth:`flats() ` method. INPUT: - - ``r`` -- A natural number. + - ``k`` -- integer OUTPUT: - A list of triples `(F, B, X)` with `F` a flat of rank ``r``, + A list of triples `(F, B, X)` with `F` a flat of rank `k`, `B` a lexicographically least basis of `F`, and `X` the remaining elements of the groundset that can potentially be lex-least extensions of the flat. @@ -2962,15 +2980,15 @@ cdef class Matroid(SageObject): [frozenset({'f'}), {'f'}, frozenset({'g'})], [frozenset({'g'}), {'g'}, frozenset()]]] """ - if r < 0: + if k < 0: return [] - loops = self._closure(set()) - flags = [[loops, set(), self.groundset() - loops]] - for r in range(r): + cdef frozenset loops = self._closure(frozenset()) + cdef list flags = [[loops, set(), self.groundset() - loops]] + for i in range(k): flags = self._extend_flags(flags) return flags - cpdef flats(self, r): + cpdef SetSystem flats(self, long k): r""" Return the collection of flats of the matroid of specified rank. @@ -2978,9 +2996,9 @@ cdef class Matroid(SageObject): INPUT: - - ``r`` -- A natural number. + - ``k`` -- integer - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -2994,9 +3012,9 @@ cdef class Matroid(SageObject): ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] """ - return SetSystem(self.groundset(), subsets=[f[0] for f in self._flags(r)]) + return SetSystem(self.groundset(), subsets=[f[0] for f in self._flags(k)]) - cpdef coflats(self, r): + cpdef SetSystem coflats(self, long k): r""" Return the collection of coflats of the matroid of specified corank. @@ -3004,9 +3022,9 @@ cdef class Matroid(SageObject): INPUT: - - ``r`` -- a nonnegative integer + - ``k`` -- integer - OUTPUT: a :class:`SetSystem` + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -3014,13 +3032,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.catalog.Q6() # needs sage.rings.finite_rings + sage: M = matroids.catalog.Q6() # needs sage.rings.finite_rings sage: sorted([sorted(F) for F in M.coflats(2)]) # needs sage.rings.finite_rings [['a', 'b'], ['a', 'c'], ['a', 'd', 'f'], ['a', 'e'], ['b', 'c'], ['b', 'd'], ['b', 'e'], ['b', 'f'], ['c', 'd'], ['c', 'e', 'f'], ['d', 'e']] """ - return self.dual().flats(r) + return self.dual().flats(k) def lattice_of_flats(self): """ @@ -3037,14 +3055,14 @@ cdef class Matroid(SageObject): for X in self.flats(i)] return LatticePoset((F, lambda x, y: x < y)) - cpdef hyperplanes(self): + cpdef SetSystem hyperplanes(self): """ - Return the set of hyperplanes of the matroid. + Return the hyperplanes of the matroid. A *hyperplane* is a flat of rank ``self.full_rank() - 1``. A *flat* is a closed set. - OUTPUT: an iterable containing all hyperplanes of the matroid + OUTPUT: :class:`SetSystem` .. SEEALSO:: @@ -3058,7 +3076,7 @@ cdef class Matroid(SageObject): """ return self.flats(self.full_rank() - 1) - cpdef f_vector(self): + cpdef list f_vector(self): r""" Return the `f`-vector of the matroid. @@ -3066,7 +3084,7 @@ cdef class Matroid(SageObject): number of independent sets of rank `i`, and `r` is the rank of the matroid. - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -3083,12 +3101,12 @@ cdef class Matroid(SageObject): cdef int i, s for i in range(self.full_rank() + 1): s = 0 - for _ in self.independent_r_sets_iterator(i): + for _ in self.independent_sets_iterator(i): s += 1 f.append(ZZ(s)) return f - cpdef whitney_numbers(self): + cpdef list whitney_numbers(self): r""" Return the Whitney numbers of the first kind of the matroid. @@ -3098,7 +3116,7 @@ cdef class Matroid(SageObject): matroid's characteristic polynomial. Moreover, `|w_i|` is the number of `(i-1)`-dimensional faces of the broken circuit complex of the matroid. - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -3117,7 +3135,7 @@ cdef class Matroid(SageObject): abs_w[len(S)] += 1 return [ZZ((-1)**i * val) for i, val in enumerate(abs_w) if val != 0] - cpdef whitney_numbers2(self): + cpdef list whitney_numbers2(self): r""" Return the Whitney numbers of the second kind of the matroid. @@ -3125,7 +3143,7 @@ cdef class Matroid(SageObject): `(W_0, \ldots, W_r)`, where `W_i` is the number of flats of rank `i`, and `r` is the rank of the matroid. - OUTPUT: a list of integers + OUTPUT: list of integers EXAMPLES:: @@ -3133,7 +3151,7 @@ cdef class Matroid(SageObject): sage: M.whitney_numbers2() [1, 11, 20, 1] """ - loops = self._closure(set()) + loops = self._closure(frozenset()) flags = [[loops, set(), self.groundset() - loops]] W = [ZZ.one()] for r in range(self.full_rank()): @@ -3141,9 +3159,9 @@ cdef class Matroid(SageObject): W.append(ZZ(len(flags))) return W - cpdef broken_circuits(self, ordering=None): + cpdef SetSystem broken_circuits(self, ordering=None): r""" - Return the list of broken circuits of ``self``. + Return the broken circuits of ``self``. Let `M` be a matroid with groundset `E`, and let `<` be a total ordering on `E`. A *broken circuit* for `M` means a subset `B` of @@ -3152,7 +3170,7 @@ cdef class Matroid(SageObject): INPUT: - - ``ordering`` -- a total ordering of the groundset given as a list + - ``ordering`` -- list (optional); a total ordering of the groundset EXAMPLES:: @@ -3175,15 +3193,15 @@ cdef class Matroid(SageObject): if len(orderset) != len(self.groundset()) or orderset != self.groundset(): raise ValueError("not an ordering of the groundset") ordering = list(ordering) - ret = set() + BC = set() for C in self.circuits_iterator(): for k in ordering: if k in C: - ret.add(frozenset(C).difference([k])) + BC.add(frozenset(C).difference([k])) break - return frozenset(ret) + return SetSystem(self.groundset(), BC) - cpdef no_broken_circuits_sets(self, ordering=None): + cpdef SetSystem no_broken_circuits_sets(self, ordering=None): r""" Return the no broken circuits (NBC) sets of ``self``. @@ -3192,9 +3210,9 @@ cdef class Matroid(SageObject): INPUT: - - ``ordering`` -- a total ordering of the groundset given as a list + - ``ordering`` -- list (optional); a total ordering of the groundset - OUTPUT: a list of frozensets + OUTPUT: :class:`SetSystem` EXAMPLES:: @@ -3229,7 +3247,7 @@ cdef class Matroid(SageObject): modified from the published algorithm. """ if self.loops(): - return [] + return SetSystem(self.groundset()) cdef list rev_order if ordering is None: @@ -3245,7 +3263,8 @@ cdef class Matroid(SageObject): cdef Py_ssize_t Tmax = len(rev_order) cdef dict reverse_dict = {value: key for key, value in enumerate(rev_order)} - cdef list H, Ht, temp, B = [frozenset()] + cdef list H, Ht, temp + cdef SetSystem NBC = SetSystem(self.groundset(), [frozenset()]) cdef list next_level = [[val] for val in rev_order] cdef list cur_level cdef Py_ssize_t i = 0 @@ -3267,9 +3286,9 @@ cdef class Matroid(SageObject): break Ht[i-tp] = temp if is_indep: - B.append(frozenset(H)) + NBC.append(frozenset(H)) next_level.extend(Ht) - return SetSystem(self.groundset(), B) + return NBC def no_broken_circuits_sets_iterator(self, ordering=None): r""" @@ -3280,7 +3299,7 @@ cdef class Matroid(SageObject): INPUT: - - ``ordering`` -- a total ordering of the groundset given as a list + - ``ordering`` -- list (optional); a total ordering of the groundset EXAMPLES:: @@ -3510,7 +3529,7 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid - ``certificate`` -- boolean (default: ``False``) OUTPUT: boolean, and, if ``certificate=True``, a dictionary or @@ -3550,7 +3569,7 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid - ``certificate`` -- boolean (default: ``False``) OUTPUT: boolean, and, if ``certificate=True``, a dictionary giving the @@ -3578,7 +3597,7 @@ cdef class Matroid(SageObject): return self._is_isomorphic(other), self._isomorphism(other) if self is other: return True - return (self.full_rank() == other.full_rank() and SetSystem(self.groundset(), list(self.nonbases()))._isomorphism(SetSystem(other.groundset(), list(other.nonbases()))) is not None) + return (self.full_rank() == other.full_rank() and SetSystem(self.groundset(), self.nonbases())._isomorphism(SetSystem(other.groundset(), other.nonbases())) is not None) cpdef isomorphism(self, other): r""" @@ -3591,9 +3610,9 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid - OUTPUT: a dictionary, or ``None`` + OUTPUT: dictionary or ``None`` EXAMPLES:: @@ -3625,9 +3644,9 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid - OUTPUT: a dictionary, or ``None`` + OUTPUT: dictionary or ``None`` EXAMPLES:: @@ -3644,7 +3663,7 @@ cdef class Matroid(SageObject): if self is other: return {e:e for e in self.groundset()} if self.full_rank() == other.full_rank(): - return SetSystem(self.groundset(), list(self.nonbases()))._isomorphism(SetSystem(other.groundset(), list(other.nonbases()))) + return SetSystem(self.groundset(), self.nonbases())._isomorphism(SetSystem(other.groundset(), other.nonbases())) else: return None @@ -3658,7 +3677,7 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid OUTPUT: boolean @@ -3742,7 +3761,7 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid - ``morphism`` -- a map; can be, for instance, a dictionary, function, or permutation @@ -3879,7 +3898,7 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid + - ``other`` -- matroid - ``morphism`` -- a dictionary mapping the groundset of ``self`` to the groundset of ``other``. @@ -5054,7 +5073,7 @@ cdef class Matroid(SageObject): B = self.basis() components = [frozenset([e]) for e in self.groundset()] for e in self.groundset() - B: - C = self.circuit(B | set([e])) + C = self._circuit(B | set([e])) components2 = [] for comp in components: if (C & comp): @@ -5123,7 +5142,7 @@ cdef class Matroid(SageObject): - ``T`` -- (optional) a subset (or any iterable) of the groundset disjoint from ``S`` - OUTPUT: an integer + OUTPUT: integer EXAMPLES:: @@ -5163,7 +5182,7 @@ cdef class Matroid(SageObject): - ``S`` -- a subset of the groundset - ``T`` -- (optional) a subset of the groundset disjoint from ``S`` - OUTPUT: an integer + OUTPUT: integer ALGORITHM: @@ -5173,7 +5192,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.BetsyRoss() - sage: M._connectivity(set('ab'), set('cd')) + sage: M._connectivity(frozenset('ab'), frozenset('cd')) 2 """ return len(self._link(S,T)[0]) - self.full_rank() + self.rank(S) + self.rank(T) @@ -5256,8 +5275,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.BetsyRoss() - sage: S = set('ab') - sage: T = set('cd') + sage: S = frozenset('ab') + sage: T = frozenset('cd') sage: I, X = M._link(S, T) sage: M.connectivity(X) 2 @@ -5267,7 +5286,7 @@ cdef class Matroid(SageObject): 2 """ # compute maximal common independent set of self\S/T and self/T\S - F = set(self.groundset()) - (S | T) + F = self.groundset() - (S | T) I = self._augment(S|T, F) found_path = True while found_path: @@ -5313,7 +5332,7 @@ cdef class Matroid(SageObject): INPUT: - - ``k`` -- an integer greater or equal to 1 + - ``k`` -- integer greater or equal to 1 - ``certificate`` -- (default: ``False``) boolean; if ``True``, then return ``True, None`` if the matroid is k-connected, and ``False, X`` otherwise, where ``X`` is a `1: + if len(C) > 1: if certificate: for X in C: return False, X @@ -5611,7 +5630,7 @@ cdef class Matroid(SageObject): # now 2-separations are exact # test if groundset size is at least 4 E = set(self.groundset()) - if len(E)<4: + if len(E) < 4: if certificate: return True, None # there is no partition A,B of the groundset such that |A|, |B| >= 2 @@ -5620,8 +5639,8 @@ cdef class Matroid(SageObject): # now there exist two disjoint pairs # test if there are any parallel pairs for e in E: - X = self._closure([e]) - if len(X)>1: + X = self._closure(frozenset([e])) + if len(X) > 1: if certificate: return False, self._circuit(X) # r(C) + r(E\C) - r(E) <= r(C) < 2, |C| = 2, |E\C| >= 2 @@ -5631,14 +5650,14 @@ cdef class Matroid(SageObject): e = E.pop() f = E.pop() # check 2-separations with e,f on the same side - S = {e, f} + S = frozenset([e, f]) G = set(E) while G: g = G.pop() H = set(G) while H: h = H.pop() - T = {g, h} + T = frozenset([g, h]) I, X = self._link(S, T) # check if connectivity between S,T is < 2 if len(I) + 2 < self.full_rank(): # note: rank(S) = rank(T) = 2 @@ -5650,11 +5669,11 @@ cdef class Matroid(SageObject): H.intersection_update(self._closure(I.union([g]))) g = E.pop() # check 2-separations with e,g on one side, f on the other - S = {e, g} + S = frozenset([e, g]) H = set(E) while H: h = H.pop() - T = {f, h} + T = frozenset([f, h]) I, X = self._link(S, T) # check if connectivity between S,T is < 2 if len(I) + 2 < self.full_rank(): # note: rank(S) = rank(T) = 2 @@ -5665,11 +5684,11 @@ cdef class Matroid(SageObject): # if h' is not spanned by I + f, then I is a connector for {e, g}, {f, h'} H.intersection_update(self._closure(I.union([f]))) # check all 2-separations with f,g on one side, e on the other - S = {f, g} + S = frozenset([f, g]) H = set(E) while H: h = H.pop() - T = {e, h} + T = frozenset([e, h]) I, X = self._link(S, T) # check if connectivity between S,T is < 2 if len(I) + 2 < self.full_rank(): # note: rank(S) = rank(T) = 2 @@ -5735,16 +5754,16 @@ cdef class Matroid(SageObject): Y = set(self.groundset()-X) # Dictionary allow conversion between two representations - dX = dict(zip(range(len(X)),X)) - dY = dict(zip(range(len(Y)),Y)) - rdX = dict(zip(X,range(len(X)))) - rdY = dict(zip(Y,range(len(Y)))) + dX = dict(zip(range(len(X)), X)) + dY = dict(zip(range(len(Y)), Y)) + rdX = dict(zip(X, range(len(X)))) + rdY = dict(zip(Y, range(len(Y)))) # the partial matrix - M = matrix(len(X),len(Y)) + M = matrix(len(X), len(Y)) for y in Y: - for x in (X & self.fundamental_circuit(X,y)): - M[rdX[x],rdY[y]]=1 + for x in (X & self.fundamental_circuit(X, y)): + M[rdX[x], rdY[y]]=1 for (x,y) in spanning_forest(M): P_rows=set([dX[x]]) @@ -5801,13 +5820,13 @@ cdef class Matroid(SageObject): X = set(self.basis()) Y = set(self.groundset()-X) - dX = dict(zip(range(len(X)),X)) - dY = dict(zip(range(len(Y)),Y)) - rdX = dict(zip(X,range(len(X)))) - rdY = dict(zip(Y,range(len(Y)))) + dX = dict(zip(range(len(X)), X)) + dY = dict(zip(range(len(Y)), Y)) + rdX = dict(zip(X, range(len(X)))) + rdY = dict(zip(Y, range(len(Y)))) # the partial matrix - M = matrix(len(X),len(Y)) + M = matrix(len(X), len(Y)) for y in Y: for x in (X & self.fundamental_circuit(X,y)): M[rdX[x],rdY[y]]=1 @@ -5969,18 +5988,18 @@ cdef class Matroid(SageObject): True """ - X_1 = set(X_1) - X_2 = set(X_2) - Y_1 = set(Y_1) - Y_2 = set(Y_2) + X_1 = frozenset(X_1) + X_2 = frozenset(X_2) + Y_1 = frozenset(Y_1) + Y_2 = frozenset(Y_2) lX_2 = len(X_2) lY_2 = len(Y_2) Y = self.groundset()-X # Returns true if there is a m-separator - if (self.rank(Y_2|(X-X_1)) - len(X-X_1) - + self.rank(Y_1|(X-X_2)) - len(X-X_2) != m-1): + if (self._rank(Y_2|(X-X_1)) - len(X-X_1) + + self._rank(Y_1|(X-X_2)) - len(X-X_2) != m-1): return False, None if len(X_1|Y_1) < m: return False, None @@ -5990,28 +6009,28 @@ cdef class Matroid(SageObject): #rowshifts rowshift = False for x in set(remainX): - if (self.rank(Y_1|(X-(X_2|set([x])))) - len(X-(X_2|set([x]))) - > self.rank(Y_1|(X-X_2)) - len(X-X_2)): - X_1.add(x) + if (self._rank(Y_1|(X-(X_2|set([x])))) - len(X-(X_2|set([x]))) + > self._rank(Y_1|(X-X_2)) - len(X-X_2)): + X_1 = X_1 | {x} remainX.remove(x) rowshift = True #colshifts colshift = False for y in set(remainY): - if (self.rank(Y_2|set([y])|(X-X_1)) - len(X-X_1) - > self.rank(Y_2|(X-X_1)) - len(X-X_1)): - Y_1.add(y) + if (self._rank(Y_2|set([y])|(X-X_1)) - len(X-X_1) + > self._rank(Y_2|(X-X_1)) - len(X-X_1)): + Y_1 = Y_1 | {y} remainY.remove(y) colshift = True if not colshift and not rowshift: break - X_2 = X-X_1 - Y_2 = Y-Y_1 - S_2 = X_2|Y_2 + X_2 = X - X_1 + Y_2 = Y - Y_1 + S_2 = X_2 | Y_2 if len(S_2) < m: return False, None - if (lX_2==len(X_2) and lY_2==len(Y_2)): + if (lX_2 == len(X_2) and lY_2 == len(Y_2)): return False, None return True, S_2 @@ -6165,7 +6184,7 @@ cdef class Matroid(SageObject): return False return True - cpdef is_paving(self): + cpdef bint is_paving(self): """ Return if ``self`` is paving. @@ -6188,7 +6207,7 @@ cdef class Matroid(SageObject): return False return True - cpdef is_sparse_paving(self): + cpdef bint is_sparse_paving(self): """ Return if ``self`` is sparse-paving. @@ -6234,9 +6253,11 @@ cdef class Matroid(SageObject): [Oxl2011]_, p. 327. """ + cdef frozenset X + cdef int k for k in range(self.rank() + 2): - for X in combinations(self.groundset(), k): - X = frozenset(X) + for Xt in combinations(self.groundset(), k): + X = frozenset(Xt) if self._is_circuit(X): return k from sage.rings.infinity import infinity @@ -6253,11 +6274,9 @@ cdef class Matroid(SageObject): INPUT: - - ``basis`` -- (optional) a set; the basis `B` as above - - OUTPUT: + - ``basis`` -- set (optional); the basis `B` as above - A :class:`BinaryMatroid `. + OUTPUT: :class:`BinaryMatroid ` EXAMPLES:: @@ -6272,8 +6291,7 @@ cdef class Matroid(SageObject): """ if basis is None: basis = self.basis() - basis = list(basis) - E = list(self.groundset()) + cdef list E = list(self.groundset()) idx = {Ei: i for i, Ei in enumerate(E)} A = BinaryMatrix(len(basis), len(E)) i = 0 @@ -6283,7 +6301,7 @@ cdef class Matroid(SageObject): A.set(i, idx[e]) i += 1 from sage.matroids.linear_matroid import BinaryMatroid - return BinaryMatroid(groundset=E, matrix=A, basis=basis, keep_initial_representation=False) + return BinaryMatroid(groundset=E, matrix=A, basis=list(basis), keep_initial_representation=False) cpdef binary_matroid(self, randomized_tests=1, verify = True): r""" @@ -6419,6 +6437,8 @@ cdef class Matroid(SageObject): if basis is None: basis = self.basis() + entries = [(e, f, (e, f)) for e in basis for f in self._fundamental_cocircuit(basis, e).difference([e])] + G = Graph(entries) basis = sorted(basis, key=cmp_elements_key) bdx = {basis[i]: i for i in range(len(basis))} E = sorted(self.groundset(), key=cmp_elements_key) @@ -6426,8 +6446,6 @@ cdef class Matroid(SageObject): A = TernaryMatrix(len(basis), len(E)) for e in basis: A.set(bdx[e], idx[e], 1) - entries = [(e, f, (e, f)) for e in basis for f in self._fundamental_cocircuit(basis, e).difference([e])] - G = Graph(entries) T = set() for C in G.connected_components_subgraphs(): T.update(C.min_spanning_tree()) @@ -6558,7 +6576,7 @@ cdef class Matroid(SageObject): """ return self.ternary_matroid(randomized_tests=randomized_tests, verify=True) is not None - cpdef is_graphic(self): + cpdef bint is_graphic(self): r""" Return if ``self`` is graphic. @@ -6592,7 +6610,7 @@ cdef class Matroid(SageObject): return False return True - cpdef is_regular(self): + cpdef bint is_regular(self): r""" Return if ``self`` is regular. @@ -6689,11 +6707,10 @@ cdef class Matroid(SageObject): sage: M._is_circuit_chordal(frozenset(['a','b','d','e'])) True """ - cdef set X - cdef frozenset Ax, Bx - - X = set(C) - _ = X.pop() + cdef set XX = set(C) + cdef frozenset Ax, Bx, X + _ = XX.pop() + X = frozenset(XX) # cl(X) = cl(C), and to be a chord x must be spanned by C for x in self._closure(X)-C: Ax = self._circuit(X.union([x])) @@ -6912,7 +6929,7 @@ cdef class Matroid(SageObject): r = 0 for e in Y: res.add(e) - if self._rank(res) > r: + if self._rank(frozenset(res)) > r: r += 1 else: res.discard(e) @@ -6998,11 +7015,11 @@ cdef class Matroid(SageObject): if nonneg_error: raise ValueError("nonnegative weights were expected.") Y = [e for (w, e) in wt] - res = set([]) - r = 0 + cdef set res = set() + cdef int r = 0 for e in Y: res.add(e) - if self._corank(res) > r: + if self._corank(frozenset(res)) > r: r += 1 else: res.discard(e) @@ -7083,11 +7100,11 @@ cdef class Matroid(SageObject): Y = list(X) for e in Y: res.append(e) - if self._rank(res) > r: + if self._rank(frozenset(res)) > r: r += 1 else: del res[-1] - if self._rank([e]) >= 1: + if self._rank(frozenset({e})) >= 1: return False return True @@ -7145,11 +7162,11 @@ cdef class Matroid(SageObject): if wt_dic[e] < wt_dic[res[-1]]: smres=res[:] res.append(e) - if self._rank(res) > r: + if self._rank(frozenset(res)) > r: r += 1 else: smres.append(e) - if self._rank(smres) >= len(smres): + if self._rank(frozenset(smres)) >= len(smres): return False del smres[-1] del res[-1] @@ -7199,8 +7216,8 @@ cdef class Matroid(SageObject): sage: M.is_max_weight_coindependent_generic() False - sage: M=matroids.Uniform(2,5) - sage: wt={0: 1, 1: 1, 2: 1, 3: 2, 4: 2} + sage: M = matroids.Uniform(2, 5) + sage: wt = {0: 1, 1: 1, 2: 1, 3: 2, 4: 2} sage: M.is_max_weight_independent_generic(weights=wt) True sage: M.dual().is_max_weight_coindependent_generic(weights=wt) @@ -7238,11 +7255,11 @@ cdef class Matroid(SageObject): Y = list(X) for e in Y: res.append(e) - if self._corank(res) > r: + if self._corank(frozenset(res)) > r: r += 1 else: del res[-1] - if self._corank([e]) >= 1: + if self._corank(frozenset([e])) >= 1: return False return True @@ -7300,11 +7317,11 @@ cdef class Matroid(SageObject): if wt_dic[e] < wt_dic[res[-1]]: smres=res[:] res.append(e) - if self._corank(res) > r: + if self._corank(frozenset(res)) > r: r += 1 else: smres.append(e) - if self._corank(smres) >= len(smres): + if self._corank(frozenset(smres)) >= len(smres): return False del smres[-1] del res[-1] @@ -7397,7 +7414,7 @@ cdef class Matroid(SageObject): sage: sum([w[y] for y in Y]) 330 """ - Y = set() + Y = frozenset() U = self._intersection_augmentation(other, weights, Y) while U[0] and sum([weights[x] for x in U[1] - Y]) > sum([weights[y] for y in U[1].intersection(Y)]): Y = Y.symmetric_difference(U[1]) @@ -7410,8 +7427,8 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid with the same groundset as ``self`` - - ``weights`` -- a dictionary specifying a weight for each element of + - ``other`` -- matroid with the same groundset as ``self`` + - ``weights`` -- dictionary specifying a weight for each element of the common groundset ``E`` - ``Y`` -- an extremal common independent set of ``self`` and ``other`` of size `k`; that is, a common independent set of maximum @@ -7556,7 +7573,7 @@ cdef class Matroid(SageObject): sage: len(M._intersection_unweighted(N)) 6 """ - Y = set() + Y = frozenset() U = self._intersection_augmentation_unweighted(other, Y) while U[0]: Y = U[1] @@ -7569,8 +7586,8 @@ cdef class Matroid(SageObject): INPUT: - - ``other`` -- a matroid with the same groundset as ``self`` - - ``Y`` -- an common independent set of ``self`` and ``other`` of size `k` + - ``other`` -- matroid with the same groundset as ``self`` + - ``Y`` -- common independent set of ``self`` and ``other`` of size `k` OUTPUT: @@ -7590,10 +7607,10 @@ cdef class Matroid(SageObject): sage: Y = M.intersection(N) sage: M._intersection_augmentation_unweighted(N, Y)[0] False - sage: Y = M._intersection_augmentation_unweighted(N,set()) + sage: Y = M._intersection_augmentation_unweighted(N, frozenset()) sage: Y[0] True - sage: len(Y[1])>0 + sage: len(Y[1]) > 0 True """ E = self.groundset() @@ -7686,7 +7703,7 @@ cdef class Matroid(SageObject): exist = False if ((u in Y) and (v in E-Y) and - (not self.is_independent(Y|set([v]))) and + (self.is_dependent(Y|set([v]))) and (self.is_independent((Y|set([v])) - set([u])))): exist = True if ((u in E-Y) and @@ -7733,22 +7750,22 @@ cdef class Matroid(SageObject): # doubling search for minimum independent sets that partitions the groundset n = self.size() r = self.rank() - hi = -(-n//r) + hi = - (-n // r) lo = hi X = set() # doubling step while True: - p = PartitionMatroid([[(i,x) for i in range(hi)] for x in self.groundset()]) - X = MatroidSum([self]*hi)._intersection_unweighted(p) - if len(X)==self.size(): + p = PartitionMatroid([[(i, x) for i in range(hi)] for x in self.groundset()]) + X = MatroidSum([self] * hi)._intersection_unweighted(p) + if len(X) == self.size(): break lo = hi - hi = min(hi*2,n) + hi = min(hi * 2, n) # binary search step while lo < hi: mid = (lo+hi)//2 - p = PartitionMatroid([[(i,x) for i in range(mid)] for x in self.groundset()]) - X = MatroidSum([self]*mid)._intersection_unweighted(p) + p = PartitionMatroid([[(i, x) for i in range(mid)] for x in self.groundset()]) + X = MatroidSum([self] * mid)._intersection_unweighted(p) if len(X) != self.size(): lo = mid + 1 else: @@ -7825,9 +7842,9 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.catalog.Fano() - sage: sorted(M._external({'a', 'b', 'c'})) + sage: sorted(M._external(frozenset(['a', 'b', 'c']))) [] - sage: sorted(M._external({'e', 'f', 'g'})) + sage: sorted(M._external(frozenset(['e', 'f', 'g']))) ['a', 'b', 'c', 'd'] """ N = self.groundset() - B @@ -8003,7 +8020,7 @@ cdef class Matroid(SageObject): f = MIP.new_variable(binary=True) MIP.set_objective(sum([f[F] for F in FF])) for N in NB: - MIP.add_constraint(sum([f[F] for F in FF if len(F.intersection(N)) > self.rank(F)]), min=1) + MIP.add_constraint(sum([f[F] for F in FF if len(F.intersection(N)) > self._rank(F)]), min=1) _ = MIP.solve(log=verbose) fsol = MIP.get_values(f, convert=bool, tolerance=integrality_tolerance) @@ -8187,7 +8204,7 @@ cdef class Matroid(SageObject): lists specify groundset elements in a certain order which will be used to draw the corresponding line in geometric representation (if it exists). - - ``pos_method`` -- an integer specifying the positioning method + - ``pos_method`` -- integer specifying the positioning method - ``0``: default positioning - ``1``: use pos_dict if it is not ``None`` - ``2``: Force directed (Not yet implemented). @@ -8278,7 +8295,7 @@ cdef class Matroid(SageObject): INPUT: - - ``ordering`` -- a total ordering of the groundset given as a list + - ``ordering`` -- list (optional); a total ordering of the groundset OUTPUT: a simplicial complex of the NBC sets under inclusion @@ -8466,10 +8483,10 @@ cdef class Matroid(SageObject): for c in LM.chains(exclude=LM.maximal_elements()): if c: # the facets of IM are already present # get the cardinality of intersection of facet with IM - r = self.rank() - len(c) + r = self._rank(self.groundset()) - len(c) # get candidate independent_sets - for I in self.independent_r_sets_iterator(r): + for I in self.independent_sets_iterator(r): if I.issubset(c[0]): # add the facet @@ -8639,8 +8656,8 @@ cdef class Matroid(SageObject): def f_relabel(X): d_inv = {d[x]: x for x in self.groundset()} - X_inv = [d_inv[x] for x in X] - return self.rank(X_inv) + X_inv = frozenset([d_inv[x] for x in X]) + return self._rank(X_inv) M = RankMatroid(groundset=E, rank_function=f_relabel) return M diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 721dd653d8d..1b9860b401b 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -4,7 +4,7 @@ Theory ====== -Let `M` be a matroid with ground set `E`. There are two standard ways to +Let `M` be a matroid with groundset `E`. There are two standard ways to remove an element from `E` so that the result is again a matroid, *deletion* and *contraction*. Deletion is simply omitting the elements from a set `D` from `E` and keeping all remaining independent sets. This is denoted ``M \ D`` @@ -74,8 +74,8 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from .matroid import Matroid -from .utilities import setprint_s +from sage.matroids.matroid import Matroid +from sage.matroids.utilities import setprint_s class MinorMatroid(Matroid): @@ -91,7 +91,7 @@ class wraps around any matroid to provide an abstract minor. It INPUT: - - ``matroid`` -- a matroid. + - ``matroid`` -- matroid - ``contractions`` -- An object with Python's ``frozenset`` interface containing a subset of ``self.groundset()``. - ``deletions`` -- An object with Python's ``frozenset`` interface @@ -167,7 +167,7 @@ def _rank(self, X): INPUT: - - ``X`` -- an object with Python's ``frozenset`` interface. + - ``X`` -- an object with Python's ``frozenset`` interface OUTPUT: @@ -189,8 +189,8 @@ def _corank(self, X): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -212,8 +212,8 @@ def _max_independent(self, X): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -224,7 +224,7 @@ def _max_independent(self, X): sage: from sage.matroids.advanced import * sage: M = MinorMatroid(matroids.catalog.Vamos(), ....: contractions=set('c'), deletions={'b', 'f'}) - sage: X = M._max_independent(set(['a', 'd', 'e', 'g'])) + sage: X = M._max_independent(frozenset(['a', 'd', 'e', 'g'])) sage: sorted(X) # random ['a', 'd', 'e'] sage: M.is_independent(X) @@ -240,8 +240,8 @@ def _closure(self, X): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -252,7 +252,7 @@ def _closure(self, X): sage: from sage.matroids.advanced import * sage: M = MinorMatroid(matroids.catalog.Vamos(), ....: contractions=set('c'), deletions={'b', 'f'}) - sage: sorted(M._closure(set(['a', 'e', 'd']))) + sage: sorted(M._closure(frozenset(['a', 'e', 'd']))) ['a', 'd', 'e', 'g', 'h'] """ @@ -264,8 +264,8 @@ def _max_coindependent(self, X): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -276,7 +276,7 @@ def _max_coindependent(self, X): sage: from sage.matroids.advanced import * sage: M = MinorMatroid(matroids.catalog.Vamos(), ....: contractions=set('c'), deletions={'b', 'f'}) - sage: X = M._max_coindependent(set(['a', 'd', 'e', 'g'])) + sage: X = M._max_coindependent(frozenset(['a', 'd', 'e', 'g'])) sage: sorted(X) # random ['d', 'g'] sage: M.is_coindependent(X) @@ -292,8 +292,8 @@ def _coclosure(self, X): INPUT: - - ``X`` -- An object with Python's ``frozenset`` interface containing - a subset of ``self.groundset()``. + - ``X`` -- an object with Python's ``frozenset`` interface containing + a subset of ``self.groundset()`` OUTPUT: @@ -304,7 +304,7 @@ def _coclosure(self, X): sage: from sage.matroids.advanced import * sage: M = MinorMatroid(matroids.catalog.Vamos(), ....: contractions=set('c'), deletions={'b', 'f'}) - sage: sorted(M._coclosure(set(['a', 'b', 'c']))) + sage: sorted(M._coclosure(frozenset(['a', 'b', 'c']))) ['a', 'd', 'e', 'g', 'h'] """ @@ -316,10 +316,10 @@ def _minor(self, contractions, deletions): INPUT: - - ``contractions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. - - ``deletions`` -- An object with Python's ``frozenset`` interface - containing a subset of ``self.groundset()``. + - ``contractions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` + - ``deletions`` -- an object with Python's ``frozenset`` interface + containing a subset of ``self.groundset()`` OUTPUT: @@ -412,7 +412,7 @@ def __eq__(self, other): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid OUTPUT: @@ -444,7 +444,7 @@ def __ne__(self, other): INPUT: - - ``other`` -- A matroid. + - ``other`` -- matroid OUTPUT: @@ -468,7 +468,7 @@ def __ne__(self, other): """ return not self == other - # Copying, loading, saving: + # copying, loading, saving def __reduce__(self): r""" diff --git a/src/sage/matroids/rank_matroid.py b/src/sage/matroids/rank_matroid.py index c2ca7ccb980..88e72748c62 100644 --- a/src/sage/matroids/rank_matroid.py +++ b/src/sage/matroids/rank_matroid.py @@ -57,7 +57,7 @@ class ``RankMatroid``. All that is required is a groundset and a function that # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from .matroid import Matroid +from sage.matroids.matroid import Matroid class RankMatroid(Matroid): diff --git a/src/sage/matroids/union_matroid.pxd b/src/sage/matroids/union_matroid.pxd index d03ae476bda..518ca54bba9 100644 --- a/src/sage/matroids/union_matroid.pxd +++ b/src/sage/matroids/union_matroid.pxd @@ -4,17 +4,17 @@ from sage.matroids.matroid cimport Matroid cdef class MatroidUnion(Matroid): cdef list matroids cdef frozenset _groundset - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) cdef class MatroidSum(Matroid): cdef list summands cdef frozenset _groundset - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) cdef class PartitionMatroid(Matroid): cdef dict p cdef frozenset _groundset - cpdef groundset(self) - cpdef _rank(self, X) + cpdef frozenset groundset(self) + cpdef int _rank(self, frozenset X) diff --git a/src/sage/matroids/union_matroid.pyx b/src/sage/matroids/union_matroid.pyx index 12e9d1e7718..14097ad819b 100644 --- a/src/sage/matroids/union_matroid.pyx +++ b/src/sage/matroids/union_matroid.pyx @@ -1,7 +1,5 @@ - from sage.matroids.matroid cimport Matroid - cdef class MatroidUnion(Matroid): r""" Matroid Union. @@ -27,11 +25,9 @@ cdef class MatroidUnion(Matroid): INPUT: - - ``matroids`` -- a iterator of matroids. + - ``matroids`` -- iterator - OUTPUT: - - A ``MatroidUnion`` instance, it's a matroid union of all matroids in ``matroids``. + OUTPUT: a ``MatroidUnion`` instance; a matroid union of all matroids in ``matroids`` """ def __init__(self, matroids): """ @@ -40,7 +36,7 @@ cdef class MatroidUnion(Matroid): EXAMPLES:: sage: from sage.matroids.union_matroid import * - sage: MatroidUnion([matroids.Uniform(2,4),matroids.Uniform(5,8)]) + sage: MatroidUnion([matroids.Uniform(2, 4), matroids.Uniform(5, 8)]) Matroid of rank 7 on 8 elements as matroid union of Matroid of rank 2 on 4 elements with circuit-closures {2: {{0, 1, 2, 3}}} @@ -53,7 +49,7 @@ cdef class MatroidUnion(Matroid): E.update(M.groundset()) self._groundset = frozenset(E) - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. @@ -72,7 +68,7 @@ cdef class MatroidUnion(Matroid): """ return self._groundset - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): r""" Return the rank of a set ``X``. @@ -81,19 +77,17 @@ cdef class MatroidUnion(Matroid): INPUT: - - ``X`` -- an object with Python's ``frozenset`` interface. - - OUTPUT: + - ``X`` -- an object with Python's ``frozenset`` interface - Integer. + OUTPUT: integer EXAMPLES:: sage: from sage.matroids.union_matroid import * sage: M = MatroidSum([matroids.Uniform(2,4),matroids.Uniform(2,4)]) - sage: M._rank([(0,0),(1,0)]) + sage: M._rank(frozenset([(0,0),(1,0)])) 2 - sage: M._rank([(0,0),(0,1),(0,2),(1,0),(1,1)]) + sage: M._rank(frozenset([(0,0),(0,1),(0,2),(1,0),(1,1)])) 4 ALGORITHM: @@ -186,7 +180,7 @@ cdef class MatroidSum(Matroid): S = S + M._repr_() +"\n" return S[:-1] - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. @@ -205,7 +199,7 @@ cdef class MatroidSum(Matroid): """ return self._groundset - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): r""" Return the rank of a set ``X``. @@ -214,30 +208,28 @@ cdef class MatroidSum(Matroid): INPUT: - - ``X`` -- an object with Python's ``frozenset`` interface. - - OUTPUT: + - ``X`` -- an object with Python's ``frozenset`` interface - Integer. + OUTPUT: integer EXAMPLES:: sage: from sage.matroids.union_matroid import * sage: M = MatroidSum([matroids.Uniform(2,4),matroids.Uniform(2,4)]) - sage: M._rank([(0,0),(1,0)]) + sage: M._rank(frozenset([(0, 0), (1, 0)])) 2 - sage: M._rank([(0,0),(0,1),(0,2),(1,0),(1,1)]) + sage: M._rank(frozenset([(0, 0), (0, 1), (0, 2), (1, 0), (1, 1)])) 4 """ partition = {} - for (i,x) in X: + for (i, x) in X: if i not in partition: partition[i] = set() partition[i].add(x) - rk = 0 - for i, Xi in partition.iteritems(): - rk+= self.summands[i]._rank(Xi) - return rk + r = 0 + for (i, Xi) in partition.iteritems(): + r += self.summands[i]._rank(frozenset(Xi)) + return r cdef class PartitionMatroid(Matroid): r""" @@ -285,7 +277,7 @@ cdef class PartitionMatroid(Matroid): E.update(P) self._groundset = frozenset(E) - cpdef groundset(self): + cpdef frozenset groundset(self): """ Return the groundset of the matroid. @@ -304,7 +296,7 @@ cdef class PartitionMatroid(Matroid): """ return self._groundset - cpdef _rank(self, X): + cpdef int _rank(self, frozenset X): r""" Return the rank of a set ``X``. @@ -313,19 +305,17 @@ cdef class PartitionMatroid(Matroid): INPUT: - - ``X`` -- an object with Python's ``frozenset`` interface. + - ``X`` -- an object with Python's ``frozenset`` interface - OUTPUT: - - Integer. + OUTPUT: integer EXAMPLES:: sage: from sage.matroids.union_matroid import * - sage: M = PartitionMatroid([[1,2,3],[4,5,6]]) - sage: M._rank([1,5]) + sage: M = PartitionMatroid([[1, 2, 3], [4, 5, 6]]) + sage: M._rank(frozenset([1, 5])) 2 - sage: M._rank([1,2]) + sage: M._rank(frozenset([1, 2])) 1 """ return len(set(map(self.p.get, X))) @@ -337,7 +327,7 @@ cdef class PartitionMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.union_matroid import * - sage: PartitionMatroid([[1,2,3],[4,5,6]]) + sage: PartitionMatroid([[1, 2, 3], [4, 5, 6]]) Partition Matroid of rank 2 on 6 elements """ return "Partition " + Matroid._repr_(self)