Circuits matroids - Matroid Theory

Skip to content
Back to top
View this page
Edit this page

# Circuits matroids

Matroids are characterized by a list of circuits, which are minimal dependent sets. The `CircuitsMatroid` class implements matroids using this information as data.

A `CircuitsMatroid` can be created from another matroid or from a list of circuits. For a full description of allowed inputs, see `below`. It is recommended to use the `Matroid()` function for a more flexible way of constructing a `CircuitsMatroid` and other classes of matroids. For direct access to the `CircuitsMatroid` constructor, run:

Sage

    sage: from sage.matroids.circuits_matroid import CircuitsMatroid

Python

    >>> from sage.all import *
    >>> from sage.matroids.circuits_matroid import CircuitsMatroid

AUTHORS:

- Giorgos Mousa (2023-12-23): initial version

class sage.matroids.circuits_matroid.CircuitsMatroid

  Bases: `Matroid`

  A matroid defined by its circuits.

  INPUT:

  - `M` – matroid (default: `None`)

  - `groundset` – list (default: `None`); the groundset of the matroid

  - `circuits` – list (default: `None`); the collection of circuits of the matroid

  - `nsc_defined` – boolean (default: `False`); whether the matroid was defined by its nonspanning circuits

  Note

  For a more flexible means of input, use the `Matroid()` function.

  bases_iterator()

    Return an iterator over the bases of the matroid.

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.Uniform(2, 4))
        sage: it = M.bases_iterator()
        sage: it.__next__()
        frozenset({0, 1})
        sage: sorted(M.bases_iterator(), key=str)
        [frozenset({0, 1}),
         frozenset({0, 2}),
         frozenset({0, 3}),
         frozenset({1, 2}),
         frozenset({1, 3}),
         frozenset({2, 3})]

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.Uniform(Integer(2), Integer(4)))
        >>> it = M.bases_iterator()
        >>> it.__next__()
        frozenset({0, 1})
        >>> sorted(M.bases_iterator(), key=str)
        [frozenset({0, 1}),
         frozenset({0, 2}),
         frozenset({0, 3}),
         frozenset({1, 2}),
         frozenset({1, 3}),
         frozenset({2, 3})]

  broken_circuit_complex(ordering=None, reduced=False)

    Return the broken circuit complex of `self`.

    The broken circuit complex of a matroid with a total ordering \(<\) on the groundset is obtained from the `NBC sets` under subset inclusion.

    INPUT:

    - `ordering` – list (optional); a total ordering of the groundset

    - `reduced` – boolean (default: `False`); whether to return the reduced broken circuit complex (the link at the smallest element)

    OUTPUT: a simplicial complex of the NBC sets under inclusion

    EXAMPLES:

    Sage

        sage: M = Matroid(circuits=[[1, 2, 3], [3, 4, 5], [1, 2, 4, 5]])
        sage: M.broken_circuit_complex()
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5)}
        sage: M.broken_circuit_complex([5, 4, 3, 2, 1])
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)}
        sage: M.broken_circuit_complex([5, 4, 3, 2, 1], reduced=True)
        Simplicial complex with vertex set (1, 2, 3, 4)
         and facets {(1, 3), (1, 4), (2, 3), (2, 4)}

    Python

        >>> from sage.all import *
        >>> M = Matroid(circuits=[[Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]])
        >>> M.broken_circuit_complex()
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5)}
        >>> M.broken_circuit_complex([Integer(5), Integer(4), Integer(3), Integer(2), Integer(1)])
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)}
        >>> M.broken_circuit_complex([Integer(5), Integer(4), Integer(3), Integer(2), Integer(1)], reduced=True)
        Simplicial complex with vertex set (1, 2, 3, 4)
         and facets {(1, 3), (1, 4), (2, 3), (2, 4)}

    For a matroid with loops, the broken circuit complex is not defined, and the method yields an error:

    Sage

        sage: M = Matroid(groundset=[0, 1, 2], circuits=[[0]])
        sage: M.broken_circuit_complex()
        Traceback (most recent call last):
        ...
        ValueError: broken circuit complex of matroid with loops is not defined

    [Python]

        >>> from sage.all import *
        >>> M = Matroid(groundset=[Integer(0), Integer(1), Integer(2)], circuits=[[Integer(0)]])
        >>> M.broken_circuit_complex()
        Traceback (most recent call last):
        ...
        ValueError: broken circuit complex of matroid with loops is not defined

  circuits(k=None)

    Return the circuits of the matroid.

    INPUT:

    - `k` – integer (optional); the length of the circuits

    OUTPUT: `SetSystem`

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.Uniform(2, 4))
        sage: M.circuits()
        SetSystem of 4 sets over 4 elements
        sage: list(M.circuits(0))
        []
        sage: sorted(M.circuits(3), key=str)
        [frozenset({0, 1, 2}),
         frozenset({0, 1, 3}),
         frozenset({0, 2, 3}),
         frozenset({1, 2, 3})]

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.Uniform(Integer(2), Integer(4)))
        >>> M.circuits()
        SetSystem of 4 sets over 4 elements
        >>> list(M.circuits(Integer(0)))
        []
        >>> sorted(M.circuits(Integer(3)), key=str)
        [frozenset({0, 1, 2}),
         frozenset({0, 1, 3}),
         frozenset({0, 2, 3}),
         frozenset({1, 2, 3})]

  circuits_iterator(k=None)

    Return an iterator over the circuits of the matroid.

    INPUT:

    - `k` – integer (optional); the length of the circuits

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.Uniform(2, 4))
        sage: sum(1 for C in M.circuits_iterator())
        4
        sage: list(M.circuits_iterator(0))
        []
        sage: sorted(M.circuits_iterator(3), key=str)
        [frozenset({0, 1, 2}),
         frozenset({0, 1, 3}),
         frozenset({0, 2, 3}),
         frozenset({1, 2, 3})]

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.Uniform(Integer(2), Integer(4)))
        >>> sum(Integer(1) for C in M.circuits_iterator())
        4
        >>> list(M.circuits_iterator(Integer(0)))
        []
        >>> sorted(M.circuits_iterator(Integer(3)), key=str)
        [frozenset({0, 1, 2}),
         frozenset({0, 1, 3}),
         frozenset({0, 2, 3}),
         frozenset({1, 2, 3})]

  dependent_sets(k)

    Return the dependent sets of fixed size.

    INPUT:

    - `k` – integer

    OUTPUT: `SetSystem`

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.catalog.Vamos())
        sage: M.dependent_sets(3)
        SetSystem of 0 sets over 8 elements
        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']]

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.catalog.Vamos())
        >>> M.dependent_sets(Integer(3))
        SetSystem of 0 sets over 8 elements
        >>> sorted([sorted(X) for X in M.dependent_sets(Integer(4))])
        [['a', 'b', 'c', 'd'], ['a', 'b', 'e', 'f'], ['a', 'b', 'g', 'h'],
         ['c', 'd', 'e', 'f'], ['e', 'f', 'g', 'h']]

  full_rank()

    Return the rank of the matroid.

    The rank of the matroid is the size of the largest independent subset of the groundset.

    OUTPUT: integer

    EXAMPLES:

    Sage

        sage: M = matroids.Theta(20)
        sage: M.full_rank()
        20

    Python

        >>> from sage.all import *
        >>> M = matroids.Theta(Integer(20))
        >>> M.full_rank()
        20

  girth()

    Return the girth of the matroid.

    The girth is the size of the smallest circuit. In case the matroid has no circuits the girth is \(\infty\).

    EXAMPLES:

    Sage

        sage: matroids.Theta(10).girth()
        3

    Python

        >>> from sage.all import *
        >>> matroids.Theta(Integer(10)).girth()
        3

    REFERENCES:

    [Oxl2011], p. 327.

  groundset()

    Return the groundset of the matroid.

    The groundset is the set of elements that comprise the matroid.

    OUTPUT: set

    EXAMPLES:

    Sage

        sage: M = matroids.Theta(2)
        sage: sorted(M.groundset())
        ['x0', 'x1', 'y0', 'y1']

    Python

        >>> from sage.all import *
        >>> M = matroids.Theta(Integer(2))
        >>> sorted(M.groundset())
        ['x0', 'x1', 'y0', 'y1']

  independent_sets(k=-1)

    Return the independent sets of the matroid.

    INPUT:

    - `k` – integer (optional); if specified, return the size-\(k\) independent sets of the matroid

    OUTPUT: `SetSystem`

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.catalog.Pappus())
        sage: M.independent_sets(4)
        SetSystem of 0 sets over 9 elements
        sage: M.independent_sets(3)
        SetSystem of 75 sets over 9 elements
        sage: frozenset({'a', 'c', 'e'}) in _
        True

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.catalog.Pappus())
        >>> M.independent_sets(Integer(4))
        SetSystem of 0 sets over 9 elements
        >>> M.independent_sets(Integer(3))
        SetSystem of 75 sets over 9 elements
        >>> frozenset({'a', 'c', 'e'}) in _
        True

    See also

    `M.bases()`

  is_paving()

    Return if `self` is paving.

    A matroid is paving if each of its circuits has size \(r\) or \(r+1\).

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.catalog.Vamos())
        sage: M.is_paving()
        True

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.catalog.Vamos())
        >>> M.is_paving()
        True

  is_valid(certificate=False)

    Test if `self` obeys the matroid axioms.

    For a matroid defined by its circuits, we check the circuit axioms.

    INPUT:

    - `certificate` – boolean (default: `False`)

    OUTPUT: boolean, or (boolean, dictionary)

    EXAMPLES:

    Sage

        sage: C = [[1, 2, 3], [3, 4, 5], [1, 2, 4, 5]]
        sage: M = Matroid(circuits=C)
        sage: M.is_valid()
        True
        sage: C = [[1, 2], [1, 2, 3], [3, 4, 5], [1, 2, 4, 5]]
        sage: M = Matroid(circuits=C)
        sage: M.is_valid()
        False
        sage: C = [[3, 6], [1, 2, 3], [3, 4, 5], [1, 2, 4, 5]]
        sage: M = Matroid(circuits=C)
        sage: M.is_valid()
        False
        sage: C = [[3, 6], [1, 2, 3], [3, 4, 5], [1, 2, 6], [6, 4, 5], [1, 2, 4, 5]]
        sage: M = Matroid(circuits=C)
        sage: M.is_valid()
        True
        sage: C = [[], [1, 2, 3], [3, 4, 5], [1, 2, 4, 5]]
        sage: M = Matroid(circuits=C)
        sage: M.is_valid()
        False
        sage: C = [[1, 2, 3], [3, 4, 5]]
        sage: M = Matroid(circuits=C)
        sage: M.is_valid(certificate=True)
        (False,
         {'circuit 1': frozenset({...}),
          'circuit 2': frozenset({...}),
          'element': 3,
          'error': 'elimination axiom failed'})

    Python

        >>> from sage.all import *
        >>> C = [[Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]]
        >>> M = Matroid(circuits=C)
        >>> M.is_valid()
        True
        >>> C = [[Integer(1), Integer(2)], [Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]]
        >>> M = Matroid(circuits=C)
        >>> M.is_valid()
        False
        >>> C = [[Integer(3), Integer(6)], [Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]]
        >>> M = Matroid(circuits=C)
        >>> M.is_valid()
        False
        >>> C = [[Integer(3), Integer(6)], [Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(6)], [Integer(6), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]]
        >>> M = Matroid(circuits=C)
        >>> M.is_valid()
        True
        >>> C = [[], [Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]]
        >>> M = Matroid(circuits=C)
        >>> M.is_valid()
        False
        >>> C = [[Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)]]
        >>> M = Matroid(circuits=C)
        >>> M.is_valid(certificate=True)
        (False,
         {'circuit 1': frozenset({...}),
          'circuit 2': frozenset({...}),
          'element': 3,
          'error': 'elimination axiom failed'})

  no_broken_circuits_facets(ordering=None, reduced=False)

    Return the no broken circuits (NBC) facets of `self`.

    INPUT:

    - `ordering` – list (optional); a total ordering of the groundset

    - `reduced` – boolean (default: `False`)

    OUTPUT: `SetSystem`

    EXAMPLES:

    Sage

        sage: M = Matroid(circuits=[[0, 1, 2]])
        sage: M.no_broken_circuits_facets(ordering=[1, 0, 2])
        SetSystem of 2 sets over 3 elements
        sage: sorted([sorted(X) for X in _])
        [[0, 1], [1, 2]]
        sage: M.no_broken_circuits_facets(ordering=[1, 0, 2], reduced=True)
        SetSystem of 2 sets over 3 elements
        sage: sorted([sorted(X) for X in _])
        [[0], [2]]

    Python

        >>> from sage.all import *
        >>> M = Matroid(circuits=[[Integer(0), Integer(1), Integer(2)]])
        >>> M.no_broken_circuits_facets(ordering=[Integer(1), Integer(0), Integer(2)])
        SetSystem of 2 sets over 3 elements
        >>> sorted([sorted(X) for X in _])
        [[0, 1], [1, 2]]
        >>> M.no_broken_circuits_facets(ordering=[Integer(1), Integer(0), Integer(2)], reduced=True)
        SetSystem of 2 sets over 3 elements
        >>> sorted([sorted(X) for X in _])
        [[0], [2]]

  no_broken_circuits_sets(ordering=None, reduced=False)

    Return the no broken circuits (NBC) sets of `self`.

    An NBC set is a subset \(A\) of the groundset under some total ordering \(<\) such that \(A\) contains no broken circuit.

    INPUT:

    - `ordering` – list (optional); a total ordering of the groundset

    - `reduced` – boolean (default: `False`)

    OUTPUT: `SetSystem`

    EXAMPLES:

    Sage

        sage: M = Matroid(circuits=[[1, 2, 3], [3, 4, 5], [1, 2, 4, 5]])
        sage: SimplicialComplex(M.no_broken_circuits_sets())
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5)}
        sage: SimplicialComplex(M.no_broken_circuits_sets([5, 4, 3, 2, 1]))
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)}

    Python

        >>> from sage.all import *
        >>> M = Matroid(circuits=[[Integer(1), Integer(2), Integer(3)], [Integer(3), Integer(4), Integer(5)], [Integer(1), Integer(2), Integer(4), Integer(5)]])
        >>> SimplicialComplex(M.no_broken_circuits_sets())
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5)}
        >>> SimplicialComplex(M.no_broken_circuits_sets([Integer(5), Integer(4), Integer(3), Integer(2), Integer(1)]))
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)}

    Sage

        sage: M = Matroid(circuits=[[1, 2, 3], [1, 4, 5], [2, 3, 4, 5]])
        sage: SimplicialComplex(M.no_broken_circuits_sets([5, 4, 3, 2, 1]))
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 3, 5), (2, 3, 5), (2, 4, 5), (3, 4, 5)}

    [Python]

        >>> from sage.all import *
        >>> M = Matroid(circuits=[[Integer(1), Integer(2), Integer(3)], [Integer(1), Integer(4), Integer(5)], [Integer(2), Integer(3), Integer(4), Integer(5)]])
        >>> SimplicialComplex(M.no_broken_circuits_sets([Integer(5), Integer(4), Integer(3), Integer(2), Integer(1)]))
        Simplicial complex with vertex set (1, 2, 3, 4, 5)
         and facets {(1, 3, 5), (2, 3, 5), (2, 4, 5), (3, 4, 5)}

  nonspanning_circuits()

    Return the nonspanning circuits of the matroid.

    OUTPUT: `SetSystem`

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.Uniform(2, 4))
        sage: M.nonspanning_circuits()
        SetSystem of 0 sets over 4 elements
        sage: M = matroids.Theta(5)
        sage: M.nonspanning_circuits()
        SetSystem of 15 sets over 10 elements

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.Uniform(Integer(2), Integer(4)))
        >>> M.nonspanning_circuits()
        SetSystem of 0 sets over 4 elements
        >>> M = matroids.Theta(Integer(5))
        >>> M.nonspanning_circuits()
        SetSystem of 15 sets over 10 elements

  nonspanning_circuits_iterator()

    Return an iterator over the nonspanning circuits of the matroid.

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.Uniform(2, 4))
        sage: list(M.nonspanning_circuits_iterator())
        []

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.Uniform(Integer(2), Integer(4)))
        >>> list(M.nonspanning_circuits_iterator())
        []

  relabel(mapping)

    Return an isomorphic matroid with relabeled groundset.

    The output is obtained by relabeling each element \(e\) by `mapping[e]`, where `mapping` is a given injective map. If `mapping[e]` is not defined, then the identity map is assumed.

    INPUT:

    - `mapping` – a Python object such that `mapping[e]` is the new label of \(e\)

    OUTPUT: matroid

    EXAMPLES:

    Sage

        sage: from sage.matroids.circuits_matroid import CircuitsMatroid
        sage: M = CircuitsMatroid(matroids.catalog.RelaxedNonFano())
        sage: sorted(M.groundset())
        [0, 1, 2, 3, 4, 5, 6]
        sage: N = M.relabel({'g': 'x', 0: 'z'})  # 'g': 'x' is ignored
        sage: from sage.matroids.utilities import cmp_elements_key
        sage: sorted(N.groundset(), key=cmp_elements_key)
        [1, 2, 3, 4, 5, 6, 'z']
        sage: M.is_isomorphic(N)
        True

    Python

        >>> from sage.all import *
        >>> from sage.matroids.circuits_matroid import CircuitsMatroid
        >>> M = CircuitsMatroid(matroids.catalog.RelaxedNonFano())
        >>> sorted(M.groundset())
        [0, 1, 2, 3, 4, 5, 6]
        >>> N = M.relabel({'g': 'x', Integer(0): 'z'})  # 'g': 'x' is ignored
        >>> from sage.matroids.utilities import cmp_elements_key
        >>> sorted(N.groundset(), key=cmp_elements_key)
        [1, 2, 3, 4, 5, 6, 'z']
        >>> M.is_isomorphic(N)
        True