Linear matroids - Matroid Theory

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

# Linear matroids

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.

## Construction

The recommended way to create a linear matroid is by using the `Matroid()` function, with a representation matrix \(A\) as input. This function will intelligently choose one of the dedicated classes `BinaryMatroid`, `TernaryMatroid`, `QuaternaryMatroid`, `RegularMatroid` when appropriate. However, invoking the classes directly is possible too. To get access to them, type:

Sage

    sage: from sage.matroids.advanced import *

Python

    >>> from sage.all import *
    >>> from sage.matroids.advanced import *

See also `sage.matroids.advanced`. In both cases, it is possible to provide a reduced matrix \(B\), to create the matroid induced by \(A = [ I B ]\):

Sage

    sage: from sage.matroids.advanced import *
    sage: A = Matrix(GF(2), [[1, 0, 0, 1, 1, 0, 1], [0, 1, 0, 1, 0, 1, 1],
    ....:                    [0, 0, 1, 0, 1, 1, 1]])
    sage: B = Matrix(GF(2), [[1, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 1]])
    sage: M1 = Matroid(A)
    sage: M2 = LinearMatroid(A)
    sage: M3 = BinaryMatroid(A)
    sage: M4 = Matroid(reduced_matrix=B)
    sage: M5 = LinearMatroid(reduced_matrix=B)
    sage: isinstance(M1, BinaryMatroid)
    True
    sage: M1.equals(M2)
    True
    sage: M1.equals(M3)
    True
    sage: M1 == M4
    True
    sage: M1.is_field_isomorphic(M5)
    True
    sage: M2 == M3  # comparing LinearMatroid and BinaryMatroid always yields False
    False

[Python]

    >>> from sage.all import *
    >>> from sage.matroids.advanced import *
    >>> A = Matrix(GF(Integer(2)), [[Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(1)],
    ...                    [Integer(0), Integer(0), Integer(1), Integer(0), Integer(1), Integer(1), Integer(1)]])
    >>> B = Matrix(GF(Integer(2)), [[Integer(1), Integer(1), Integer(0), Integer(1)], [Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)]])
    >>> M1 = Matroid(A)
    >>> M2 = LinearMatroid(A)
    >>> M3 = BinaryMatroid(A)
    >>> M4 = Matroid(reduced_matrix=B)
    >>> M5 = LinearMatroid(reduced_matrix=B)
    >>> isinstance(M1, BinaryMatroid)
    True
    >>> M1.equals(M2)
    True
    >>> M1.equals(M3)
    True
    >>> M1 == M4
    True
    >>> M1.is_field_isomorphic(M5)
    True
    >>> M2 == M3  # comparing LinearMatroid and BinaryMatroid always yields False
    False

## Class methods

The `LinearMatroid` class and its derivatives inherit all methods from the `Matroid` and `BasisExchangeMatroid` classes. See the documentation for these classes for an overview. In addition, the following methods are available:

- `LinearMatroid`

  > - `base_ring()`

  > - `characteristic()`

  > - `representation()`

  > - `representation_vectors()`

  > - `is_field_equivalent()`

  > - `is_field_isomorphism()`

  > - `has_field_minor()`

  > - `fundamental_cycle()`

  > - `fundamental_cocycle()`

  > - `cross_ratios()`

  > - `cross_ratio()`

  > - `linear_extension()`

  > - `linear_coextension()`

  > - `linear_extension_chains()`

  > - `linear_coextension_cochains()`

  > - `linear_extensions()`

  > - `linear_coextensions()`

  > - `orlik_terao_algebra()`

- `BinaryMatroid` has all of the `LinearMatroid` ones, and

  > - `bicycle_dimension()`

  > - `brown_invariant()`

  > - `is_graphic()`

- `TernaryMatroid` has all of the `LinearMatroid` ones, and

  > - `bicycle_dimension()`

  > - `character()`

- `QuaternaryMatroid` has all of the `LinearMatroid` ones, and

  > - `bicycle_dimension()`

- `RegularMatroid` has all of the `LinearMatroid` ones, and

  > - `is_graphic()`

AUTHORS:

- Rudi Pendavingh, Stefan van Zwam (2013-04-01): initial version

## Methods

class sage.matroids.linear_matroid.BinaryMatroid

  Bases: `LinearMatroid`

  Binary matroids.

  A binary matroid is a linear matroid represented over the finite field with two elements. See `LinearMatroid` for a definition.

  The simplest way to create a `BinaryMatroid` is by giving only a matrix \(A\). Then, the groundset defaults to `range(A.ncols())`. Any iterable object \(E\) can be given as a groundset. If \(E\) is a list, then `E[i]` will label the \(i\)-th column of \(A\). Another possibility is to specify a reduced matrix \(B\), to create the matroid induced by \(A = [ I B ]\).

  INPUT:

  - `matrix` – (default: `None`) a matrix whose column vectors represent the matroid.

  - `reduced_matrix` – (default: `None`) a matrix \(B\) such that \([I\ \ B]\) represents the matroid, where \(I\) is an identity matrix with the same number of rows as \(B\). Only one of `matrix` and `reduced_matrix` should be provided.

  - `groundset` – (default: `None`) an iterable containing the element labels. When provided, must have the correct number of elements: the number of columns of `matrix` or the number of rows plus the number of columns of `reduced_matrix`.

  - `ring` – (default: `None`) ignored

  - `keep_initial_representation` – boolean (default: `True`); whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy.

  - `basis` – (default: `None`) when provided, this is an ordered subset of `groundset`, such that the submatrix of `matrix` indexed by `basis` is an identity matrix. In this case, no row reduction takes place in the initialization phase.

  OUTPUT: a `BinaryMatroid` instance based on the data above

  Note

  An indirect way to generate a binary matroid is through the `Matroid()` function. This is usually the preferred way, since it automatically chooses between `BinaryMatroid` and other classes. For direct access to the `BinaryMatroid` constructor, run:

  Sage

      sage: from sage.matroids.advanced import *

  Python

      >>> from sage.all import *
      >>> from sage.matroids.advanced import *

  EXAMPLES:

  Sage

      sage: A = Matrix(GF(2), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]])
      sage: M = Matroid(A)
      sage: M
      Binary matroid of rank 2 on 4 elements, type (0, 6)
      sage: sorted(M.groundset())
      [0, 1, 2, 3]
      sage: Matrix(M)
      [1 0 1 1]
      [0 1 1 1]
      sage: M = Matroid(matrix=A, groundset='abcd')
      sage: sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      sage: B = Matrix(GF(2), 2, 2, [[1, 1], [1, 1]])
      sage: N = Matroid(reduced_matrix=B, groundset='abcd')
      sage: M == N
      True

  Python

      >>> from sage.all import *
      >>> A = Matrix(GF(Integer(2)), Integer(2), Integer(4), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)]])
      >>> M = Matroid(A)
      >>> M
      Binary matroid of rank 2 on 4 elements, type (0, 6)
      >>> sorted(M.groundset())
      [0, 1, 2, 3]
      >>> Matrix(M)
      [1 0 1 1]
      [0 1 1 1]
      >>> M = Matroid(matrix=A, groundset='abcd')
      >>> sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      >>> B = Matrix(GF(Integer(2)), Integer(2), Integer(2), [[Integer(1), Integer(1)], [Integer(1), Integer(1)]])
      >>> N = Matroid(reduced_matrix=B, groundset='abcd')
      >>> M == N
      True

  base_ring()

    Return the base ring of the matrix representing the matroid, in this case \(\GF{2}\).

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: M.base_ring()
        Finite Field of size 2

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> M.base_ring()
        Finite Field of size 2

  bicycle_dimension()

    Return the bicycle dimension of the binary matroid.

    The bicycle dimension of a linear subspace \(V\) is \(\dim(V\cap V^\perp)\). The bicycle dimension of a matroid equals the bicycle dimension of its cocycle-space, and is an invariant for binary matroids. See [Pen2012], [GR2001] for more information.

    OUTPUT: integer

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: M.bicycle_dimension()
        3

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> M.bicycle_dimension()
        3

  binary_matroid(randomized_tests=1, verify=True)

    Return a binary matroid representing `self`.

    INPUT:

    - `randomized_tests` – ignored

    - `verify` – ignored

    OUTPUT: a binary matroid

    ALGORITHM:

    `self` is a binary matroid, so just return `self`.

    See also

    `M.binary_matroid()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.Fano()
        sage: N.binary_matroid() is N
        True

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.Fano()
        >>> N.binary_matroid() is N
        True

  brown_invariant()

    Return the value of Brown’s invariant for the binary matroid.

    For a binary space \(V\), consider the sum \(B(V):=\sum_{v\in V} i^{|v|}\), where \(|v|\) denotes the number of nonzero entries of a binary vector \(v\). The value of the Tutte Polynomial in the point \((-i, i)\) can be expressed in terms of \(B(V)\), see [Pen2012]. If \(|v|\) equals \(2\) modulo 4 for some \(v\in V\cap V^\perp\), then \(B(V)=0\). In this case, Browns invariant is not defined. Otherwise, \(B(V)=\sqrt{2}^k \exp(\sigma \pi i/4)\) for some integers \(k, \sigma\). In that case, \(k\) equals the bycycle dimension of \(V\), and Browns invariant for \(V\) is defined as \(\sigma\) modulo \(8\).

    The Brown invariant of a binary matroid equals the Brown invariant of its cocycle-space.

    OUTPUT: integer

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: M.brown_invariant()
        0
        sage: M = Matroid(Matrix(GF(2), 3, 8, [[1, 0, 0, 1, 1, 1, 1, 1],
        ....:                                  [0, 1, 0, 1, 1, 0, 0, 0],
        ....:                                  [0, 0, 1, 0, 0, 1, 1, 0]]))
        sage: M.brown_invariant() is None
        True

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> M.brown_invariant()
        0
        >>> M = Matroid(Matrix(GF(Integer(2)), Integer(3), Integer(8), [[Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)],
        ...                                  [Integer(0), Integer(1), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0)],
        ...                                  [Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0)]]))
        >>> M.brown_invariant() is None
        True

  characteristic()

    Return the characteristic of the base ring of the matrix representing the matroid, in this case \(2\).

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: M.characteristic()
        2

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> M.characteristic()
        2

  is_binary(randomized_tests=1)

    Decide if `self` is a binary matroid.

    INPUT:

    - `randomized_tests` – ignored

    OUTPUT: boolean

    ALGORITHM:

    `self` is a binary matroid, so just return `True`.

    See also

    `M.is_binary()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.Fano()
        sage: N.is_binary()
        True

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.Fano()
        >>> N.is_binary()
        True

  is_graphic()

    Test if the binary matroid is graphic.

    A matroid is graphic if there exists a graph whose edge set equals the groundset of the matroid, such that a subset of elements of the matroid is independent if and only if the corresponding subgraph is acyclic.

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: R10 = matroids.catalog.R10()
        sage: M = Matroid(ring=GF(2), reduced_matrix=R10.representation(
        ....:                                 reduced=True, labels=False))
        sage: M.is_graphic()
        False
        sage: K5 = Matroid(graphs.CompleteGraph(5), regular=True)                   # needs sage.graphs
        sage: M = Matroid(ring=GF(2), reduced_matrix=K5.representation(             # needs sage.graphs sage.rings.finite_rings
        ....:                                 reduced=True, labels=False))
        sage: M.is_graphic()                                                        # needs sage.graphs sage.rings.finite_rings
        True
        sage: M.dual().is_graphic()                                                 # needs sage.graphs
        False

    Python

        >>> from sage.all import *
        >>> R10 = matroids.catalog.R10()
        >>> M = Matroid(ring=GF(Integer(2)), reduced_matrix=R10.representation(
        ...                                 reduced=True, labels=False))
        >>> M.is_graphic()
        False
        >>> K5 = Matroid(graphs.CompleteGraph(Integer(5)), regular=True)                   # needs sage.graphs
        >>> M = Matroid(ring=GF(Integer(2)), reduced_matrix=K5.representation(             # needs sage.graphs sage.rings.finite_rings
        ...                                 reduced=True, labels=False))
        >>> M.is_graphic()                                                        # needs sage.graphs sage.rings.finite_rings
        True
        >>> M.dual().is_graphic()                                                 # needs sage.graphs
        False

    ALGORITHM:

    In a recent paper, Geelen and Gerards [GG2012] reduced the problem to testing if a system of linear equations has a solution. While not the fastest method, and not necessarily constructive (in the presence of 2-separations especially), it is easy to implement.

  is_valid(certificate=False)

    Test if the data obey the matroid axioms.

    Since this is a linear matroid over the field \(\GF{2}\), this is always the case.

    INPUT:

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

    OUTPUT: `True`, or `(True, {})`

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(2), [[]]))
        sage: M.is_valid()
        True

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(2)), [[]]))
        >>> M.is_valid()
        True

  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: M = matroids.catalog.Fano()
        sage: sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        sage: N = M.relabel({'g': 'x'})
        sage: sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        >>> N = M.relabel({'g': 'x'})
        >>> sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

class sage.matroids.linear_matroid.LinearMatroid

  Bases: `BasisExchangeMatroid`

  Linear matroids.

  When \(A\) is an \(r\) times \(E\) matrix, the linear matroid \(M[A]\) has ground set \(E\) and set of independent sets

  > \(I(A) =\{F \subseteq E :\) the columns of \(A\) indexed by \(F\) are linearly independent \(\}\)

  The simplest way to create a LinearMatroid is by giving only a matrix \(A\). Then, the groundset defaults to `range(A.ncols())`. Any iterable object `E` can be given as a groundset. If `E` is a list, then `E[i]` will label the \(i\)-th column of \(A\). Another possibility is to specify a reduced matrix \(B\), to create the matroid induced by \(A = [ I B ]\).

  INPUT:

  - `matrix` – (default: `None`) a matrix whose column vectors represent the matroid

  - `reduced_matrix` – (default: `None`) a matrix \(B\) such that \([I\ \ B]\) represents the matroid, where \(I\) is an identity matrix with the same number of rows as \(B\). Only one of `matrix` and `reduced_matrix` should be provided.

  - `groundset` – (default: `None`) an iterable containing the element labels. When provided, must have the correct number of elements: the number of columns of `matrix` or the number of rows plus the number of columns of `reduced_matrix`.

  - `ring` – (default: `None`) the desired base ring of the matrix. If the base ring is different, an attempt will be made to create a new matrix with the correct base ring.

  - `keep_initial_representation` – boolean (default: `True`); whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy.

  OUTPUT: a `LinearMatroid` instance based on the data above

  Note

  The recommended way to generate a linear matroid is through the `Matroid()` function. It will automatically choose more optimized classes when present (currently `BinaryMatroid`, `TernaryMatroid`, `QuaternaryMatroid`, `RegularMatroid`). For direct access to the `LinearMatroid` constructor, run:

  Sage

      sage: from sage.matroids.advanced import *

  Python

      >>> from sage.all import *
      >>> from sage.matroids.advanced import *

  EXAMPLES:

  Sage

      sage: from sage.matroids.advanced import *
      sage: A = Matrix(GF(3), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 2]])
      sage: M = LinearMatroid(A)
      sage: M
      Linear matroid of rank 2 on 4 elements represented over the Finite
      Field of size 3
      sage: sorted(M.groundset())
      [0, 1, 2, 3]
      sage: Matrix(M)
      [1 0 1 1]
      [0 1 1 2]
      sage: M = LinearMatroid(A, 'abcd')
      sage: sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      sage: B = Matrix(GF(3), 2, 2, [[1, 1], [1, 2]])
      sage: N = LinearMatroid(reduced_matrix=B, groundset='abcd')
      sage: M == N
      True

  Python

      >>> from sage.all import *
      >>> from sage.matroids.advanced import *
      >>> A = Matrix(GF(Integer(3)), Integer(2), Integer(4), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(2)]])
      >>> M = LinearMatroid(A)
      >>> M
      Linear matroid of rank 2 on 4 elements represented over the Finite
      Field of size 3
      >>> sorted(M.groundset())
      [0, 1, 2, 3]
      >>> Matrix(M)
      [1 0 1 1]
      [0 1 1 2]
      >>> M = LinearMatroid(A, 'abcd')
      >>> sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      >>> B = Matrix(GF(Integer(3)), Integer(2), Integer(2), [[Integer(1), Integer(1)], [Integer(1), Integer(2)]])
      >>> N = LinearMatroid(reduced_matrix=B, groundset='abcd')
      >>> M == N
      True

  base_ring()

    Return the base ring of the matrix representing the matroid.

    EXAMPLES:

    Sage

        sage: M = Matroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1],
        ....:                                   [0, 1, 1, 2, 3]]))
        sage: M.base_ring()
        Finite Field of size 5

    Python

        >>> from sage.all import *
        >>> M = Matroid(matrix=Matrix(GF(Integer(5)), [[Integer(1), Integer(0), Integer(1), Integer(1), Integer(1)],
        ...                                   [Integer(0), Integer(1), Integer(1), Integer(2), Integer(3)]]))
        >>> M.base_ring()
        Finite Field of size 5

  central_zonotopal_algebra(base_ring=None)

    Return the central zonotopal algebra of `self` over `base_ring`.

    We use the presentation given in Section 3.1 of [HR2011]. Let \(M\) be a linear matroid, and let \(L(M)\) denote the dependent sets of the dual matroid. Then the defining ideal is generated by

    \[I(M) := \langle p_Y = \prod_{y \in Y} S(y) \mid Y \in L(M) \rangle,\]

    where we consider \(Y\) as a set of column vectors of the defining `representation()` \(\overline{M}\) of \(M\) and \(S(y)\) is the corresponding linear polynomial in the symmetric space \(S(V)\) with \(V\) being the column space of \(\overline{M}\).

    See also

    - `zonotopal_algebra()`

    - `internal_zonotopal_algebra()`

    EXAMPLES:

    We construct Example 3.10 in [HR2011]:

    Sage

        sage: mat = matrix([[1,0,0,1,1,0], [0,1,0,-1,0,1], [0,0,1,0,-1,-1]]); mat
        [ 1  0  0  1  1  0]
        [ 0  1  0 -1  0  1]
        [ 0  0  1  0 -1 -1]
        sage: M = Matroid(mat)
        sage: Z = M.central_zonotopal_algebra()
        sage: Z.defining_ideal().hilbert_series()
        6*t^3 + 6*t^2 + 3*t + 1
        sage: M.zonotopal_algebra(-1).defining_ideal().hilbert_series()
        6*t^3 + 6*t^2 + 3*t + 1

    Python

        >>> from sage.all import *
        >>> mat = matrix([[Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0)], [Integer(0),Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)], [Integer(0),Integer(0),Integer(1),Integer(0),-Integer(1),-Integer(1)]]); mat
        [ 1  0  0  1  1  0]
        [ 0  1  0 -1  0  1]
        [ 0  0  1  0 -1 -1]
        >>> M = Matroid(mat)
        >>> Z = M.central_zonotopal_algebra()
        >>> Z.defining_ideal().hilbert_series()
        6*t^3 + 6*t^2 + 3*t + 1
        >>> M.zonotopal_algebra(-Integer(1)).defining_ideal().hilbert_series()
        6*t^3 + 6*t^2 + 3*t + 1

  characteristic()

    Return the characteristic of the base ring of the matrix representing the matroid.

    EXAMPLES:

    Sage

        sage: M = Matroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1],
        ....:                                   [0, 1, 1, 2, 3]]))
        sage: M.characteristic()
        5

    Python

        >>> from sage.all import *
        >>> M = Matroid(matrix=Matrix(GF(Integer(5)), [[Integer(1), Integer(0), Integer(1), Integer(1), Integer(1)],
        ...                                   [Integer(0), Integer(1), Integer(1), Integer(2), Integer(3)]]))
        >>> M.characteristic()
        5

  cross_ratio(F, a, b, c, d)

    Return the cross ratio of the four ordered points `a, b, c, d` after contracting a flat `F` of codimension 2.

    Consider the following matrix with columns labeled by \(\{a, b, c, d\}\).

    \[\begin{split}\begin{bmatrix} 1 & 0 & 1 & 1\\ 0 & 1 & x & 1 \end{bmatrix}\end{split}\]

    The cross ratio of the ordered tuple \((a, b, c, d)\) equals \(x\). This method looks at such minors where `F` is a flat to be contracted, and all remaining elements other than `a, b, c, d` are deleted.

    INPUT:

    - `F` – a flat of codimension 2

    - `a`, `b`, `c`, `d` – elements of the groundset

    OUTPUT:

    The cross ratio of the four points on the line obtained by contracting `F`.

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1],
        ....:                            [0, 1, 0, 1, 2, 4],
        ....:                            [0, 0, 1, 3, 2, 6]]))
        sage: M.cross_ratio([0], 1, 2, 3, 5)
        4

        sage: M = Matroid(ring=GF(7), matrix=[[1, 0, 1, 1], [0, 1, 1, 1]])
        sage: M.cross_ratio(set(), 0, 1, 2, 3)
        Traceback (most recent call last):
        ...
        ValueError: points a, b, c, d do not form a 4-point line in M/F

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
        ...                            [Integer(0), Integer(1), Integer(0), Integer(1), Integer(2), Integer(4)],
        ...                            [Integer(0), Integer(0), Integer(1), Integer(3), Integer(2), Integer(6)]]))
        >>> M.cross_ratio([Integer(0)], Integer(1), Integer(2), Integer(3), Integer(5))
        4

        >>> M = Matroid(ring=GF(Integer(7)), matrix=[[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)]])
        >>> M.cross_ratio(set(), Integer(0), Integer(1), Integer(2), Integer(3))
        Traceback (most recent call last):
        ...
        ValueError: points a, b, c, d do not form a 4-point line in M/F

  cross_ratios(hyperlines=None)

    Return the set of cross ratios that occur in this linear matroid.

    Consider the following matrix with columns labeled by \(\{a, b, c, d\}\).

    \[\begin{split}\begin{matrix} 1 & 0 & 1 & 1\\ 0 & 1 & x & 1 \end{matrix}\end{split}\]

    The cross ratio of the ordered tuple \((a, b, c, d)\) equals \(x\). The set of all cross ratios of a matroid is the set of cross ratios of all such minors.

    INPUT:

    - `hyperlines` – (optional) a set of flats of the matroid, of rank \(r - 2\), where \(r\) is the rank of the matroid. If not given, then `hyperlines` defaults to all such flats.

    OUTPUT:

    A list of all cross ratios of this linearly represented matroid that occur in rank-2 minors that arise by contracting a flat `F` in `hyperlines` (so by default, those are all cross ratios).

    See also

    `M.cross_ratio()`

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1],
        ....:                            [0, 1, 0, 1, 2, 4],
        ....:                            [0, 0, 1, 3, 2, 5]]))
        sage: sorted(M.cross_ratios())
        [2, 3, 4, 5, 6]
        sage: M = Matroid(graphs.CompleteGraph(5), regular=True)                    # needs sage.graphs
        sage: M.cross_ratios()                                                      # needs sage.graphs
        set()

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
        ...                            [Integer(0), Integer(1), Integer(0), Integer(1), Integer(2), Integer(4)],
        ...                            [Integer(0), Integer(0), Integer(1), Integer(3), Integer(2), Integer(5)]]))
        >>> sorted(M.cross_ratios())
        [2, 3, 4, 5, 6]
        >>> M = Matroid(graphs.CompleteGraph(Integer(5)), regular=True)                    # needs sage.graphs
        >>> M.cross_ratios()                                                      # needs sage.graphs
        set()

  dual()

    Return the dual of the matroid.

    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\).

    If the matroid is represented by \([I_1\ \ A]\), then the dual is represented by \([-A^T\ \ I_2]\) for appropriately sized identity matrices \(I_1, I_2\).

    OUTPUT: the dual matroid

    EXAMPLES:

    Sage

        sage: A = Matrix(GF(7), [[1, 1, 0, 1],
        ....:                    [1, 0, 1, 1],
        ....:                    [0, 1, 1, 1]])
        sage: B = - A.transpose()
        sage: Matroid(reduced_matrix=A).dual() == Matroid(
        ....:                             reduced_matrix=B,
        ....:                             groundset=[3, 4, 5, 6, 0, 1, 2])
        True

    Python

        >>> from sage.all import *
        >>> A = Matrix(GF(Integer(7)), [[Integer(1), Integer(1), Integer(0), Integer(1)],
        ...                    [Integer(1), Integer(0), Integer(1), Integer(1)],
        ...                    [Integer(0), Integer(1), Integer(1), Integer(1)]])
        >>> B = - A.transpose()
        >>> Matroid(reduced_matrix=A).dual() == Matroid(
        ...                             reduced_matrix=B,
        ...                             groundset=[Integer(3), Integer(4), Integer(5), Integer(6), Integer(0), Integer(1), Integer(2)])
        True

  fundamental_cocycle(B, e)

    Return the fundamental cycle, relative to `B`, containing element `e`.

    This is the `fundamental cocircuit` together with an appropriate signing from the field, such that \(Av=0\), where \(A\) is a representation matrix of the dual, and \(v\) the vector corresponding to the output.

    INPUT:

    - `B` – a basis of the matroid

    - `e` – an element of the basis

    OUTPUT:

    A dictionary mapping elements of `M.fundamental_cocircuit(B, e)` to elements of the ring.

    See also

    `M.fundamental_cocircuit()`

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]]))
        sage: v = M.fundamental_cocycle([0, 1], 0)
        sage: [v[0], v[2], v[3]]
        [1, 1, 1]
        sage: frozenset(v.keys()) == M.fundamental_cocircuit([0, 1], 0)
        True

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(4)]]))
        >>> v = M.fundamental_cocycle([Integer(0), Integer(1)], Integer(0))
        >>> [v[Integer(0)], v[Integer(2)], v[Integer(3)]]
        [1, 1, 1]
        >>> frozenset(v.keys()) == M.fundamental_cocircuit([Integer(0), Integer(1)], Integer(0))
        True

  fundamental_cycle(B, e)

    Return the fundamental cycle, relative to `B`, containing element `e`.

    This is the `fundamental circuit` together with an appropriate signing from the field, such that \(Av=0\), where \(A\) is the representation matrix, and \(v\) the vector corresponding to the output.

    INPUT:

    - `B` – a basis of the matroid

    - `e` – an element outside the basis

    OUTPUT:

    A dictionary mapping elements of `M.fundamental_circuit(B, e)` to elements of the ring.

    See also

    `M.fundamental_circuit()`

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]]))
        sage: v = M.fundamental_cycle([0, 1], 3)
        sage: [v[0], v[1], v[3]]
        [6, 3, 1]
        sage: frozenset(v.keys()) == M.fundamental_circuit([0, 1], 3)
        True

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(4)]]))
        >>> v = M.fundamental_cycle([Integer(0), Integer(1)], Integer(3))
        >>> [v[Integer(0)], v[Integer(1)], v[Integer(3)]]
        [6, 3, 1]
        >>> frozenset(v.keys()) == M.fundamental_circuit([Integer(0), Integer(1)], Integer(3))
        True

  has_field_minor(N)

    Check if `self` has a minor field isomorphic to `N`.

    INPUT:

    - `N` – matroid

    OUTPUT: boolean

    See also

    `M.minor()`, `M.is_field_isomorphic()`

    Todo

    This important method can (and should) be optimized considerably. See [Hli2006] p.1219 for hints to that end.

    EXAMPLES:

    Sage

        sage: M = matroids.Whirl(3)
        sage: matroids.catalog.Fano().has_field_minor(M)
        False
        sage: matroids.catalog.NonFano().has_field_minor(M)
        True

    Python

        >>> from sage.all import *
        >>> M = matroids.Whirl(Integer(3))
        >>> matroids.catalog.Fano().has_field_minor(M)
        False
        >>> matroids.catalog.NonFano().has_field_minor(M)
        True

  has_line_minor(k, hyperlines=None, certificate=False)

    Test if the matroid has a \(U_{2, k}\)-minor.

    The matroid \(U_{2, k}\) is a matroid on \(k\) elements in which every subset of at most 2 elements is independent, and every subset of more than two elements is dependent.

    The optional argument `hyperlines` restricts the search space: this method returns `True` if \(si(M/F)\) is isomorphic to \(U_{2, l}\) with \(l \geq k\) for some \(F\) in `hyperlines`, and `False` otherwise.

    INPUT:

    - `k` – the length of the line minor

    - `hyperlines` – (default: `None`) a set of flats of codimension 2. Defaults to the set of all flats of codimension 2.

    - `certificate` – (default: `False`) if `True` returns `True, F`, where `F` is a flat and `self.minor(contractions=F)` has a \(U_{2,k}\) restriction or `False, None`

    OUTPUT: boolean or tuple

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.N1()
        sage: M.has_line_minor(4)
        True
        sage: M.has_line_minor(5)
        False
        sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']])
        False
        sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'],
        ....:                                   ['a', 'b', 'd' ]])
        True
        sage: M.has_line_minor(4, certificate=True)
        (True, frozenset({'a', 'b', 'd'}))
        sage: M.has_line_minor(5, certificate=True)
        (False, None)
        sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'],
        ....:                                   ['a', 'b', 'd' ]], certificate=True)
        (True, frozenset({'a', 'b', 'd'}))

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.N1()
        >>> M.has_line_minor(Integer(4))
        True
        >>> M.has_line_minor(Integer(5))
        False
        >>> M.has_line_minor(k=Integer(4), hyperlines=[['a', 'b', 'c']])
        False
        >>> M.has_line_minor(k=Integer(4), hyperlines=[['a', 'b', 'c'],
        ...                                   ['a', 'b', 'd' ]])
        True
        >>> M.has_line_minor(Integer(4), certificate=True)
        (True, frozenset({'a', 'b', 'd'}))
        >>> M.has_line_minor(Integer(5), certificate=True)
        (False, None)
        >>> M.has_line_minor(k=Integer(4), hyperlines=[['a', 'b', 'c'],
        ...                                   ['a', 'b', 'd' ]], certificate=True)
        (True, frozenset({'a', 'b', 'd'}))

  internal_zonotopal_algebra(base_ring=None)

    Return the internal zonotopal algebra of `self` over `base_ring`.

    We use the presentation given in Section 5.1 of [HR2011]. Let \(M\) be a linear matroid, and define

    \[L_-(M) := \{ Y \subseteq E \mid Y \cap B \neq \emptyset \text{ for all bases } B \text{ with no internal activity} \}.\]

    Then the defining ideal is generated by

    \[I_-(M) := \langle p_Y = \prod_{y \in Y} S(y) \mid Y \in L_-(M) \rangle,\]

    where we consider \(Y\) as a set of column vectors of the defining `representation()` \(\overline{M}\) of \(M\) and \(S(y)\) is the corresponding linear polynomial in the symmetric space \(S(V)\) with \(V\) being the column space of \(\overline{M}\).

    See also

    - `zonotopal_algebra()`

    - `central_zonotopal_algebra()`

    EXAMPLES:

    We construct Example 5.12 in [HR2011]:

    Sage

        sage: mat = matrix([[1,0,0,1,1,1], [0,1,0,-1,2,1], [0,0,1,0,1,1]]); mat
        [ 1  0  0  1  1  1]
        [ 0  1  0 -1  2  1]
        [ 0  0  1  0  1  1]
        sage: M = Matroid(mat)
        sage: Z = M.internal_zonotopal_algebra()
        sage: Z.defining_ideal().hilbert_series()
        4*t^2 + 3*t + 1
        sage: M.zonotopal_algebra(-2).defining_ideal().hilbert_series()
        4*t^2 + 3*t + 1

    Python

        >>> from sage.all import *
        >>> mat = matrix([[Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(1)], [Integer(0),Integer(1),Integer(0),-Integer(1),Integer(2),Integer(1)], [Integer(0),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)]]); mat
        [ 1  0  0  1  1  1]
        [ 0  1  0 -1  2  1]
        [ 0  0  1  0  1  1]
        >>> M = Matroid(mat)
        >>> Z = M.internal_zonotopal_algebra()
        >>> Z.defining_ideal().hilbert_series()
        4*t^2 + 3*t + 1
        >>> M.zonotopal_algebra(-Integer(2)).defining_ideal().hilbert_series()
        4*t^2 + 3*t + 1

  is_field_equivalent(other)

    Test for matroid representation equality.

    Two linear matroids \(M\) and \(N\) with representation matrices \(A\) and \(B\) are field equivalent if they have the same groundset, and the identity map between the groundsets is an isomorphism between the representations \(A\) and \(B\). That is, one can be turned into the other using only row operations and column scaling.

    INPUT:

    - `other` – matroid

    OUTPUT: boolean

    See also

    `M.equals()`, `M.is_field_isomorphism()`, `M.is_field_isomorphic()`

    EXAMPLES:

    A `BinaryMatroid` and `LinearMatroid` use different representations of the matroid internally, so `` == `` yields `False`, even if the matroids are equal:

    Sage

        sage: from sage.matroids.advanced import *
        sage: M = matroids.catalog.Fano()
        sage: M1 = LinearMatroid(Matrix(M), groundset=M.groundset_list())
        sage: M2 = Matroid(groundset='abcdefg',
        ....:              reduced_matrix=[[0, 1, 1, 1],
        ....:                              [1, 0, 1, 1],
        ....:                              [1, 1, 0, 1]], field=GF(2))
        sage: M.equals(M1)
        True
        sage: M.equals(M2)
        True
        sage: M.is_field_equivalent(M1)
        True
        sage: M.is_field_equivalent(M2)
        True
        sage: M == M1
        False
        sage: M == M2
        True

    Python

        >>> from sage.all import *
        >>> from sage.matroids.advanced import *
        >>> M = matroids.catalog.Fano()
        >>> M1 = LinearMatroid(Matrix(M), groundset=M.groundset_list())
        >>> M2 = Matroid(groundset='abcdefg',
        ...              reduced_matrix=[[Integer(0), Integer(1), Integer(1), Integer(1)],
        ...                              [Integer(1), Integer(0), Integer(1), Integer(1)],
        ...                              [Integer(1), Integer(1), Integer(0), Integer(1)]], field=GF(Integer(2)))
        >>> M.equals(M1)
        True
        >>> M.equals(M2)
        True
        >>> M.is_field_equivalent(M1)
        True
        >>> M.is_field_equivalent(M2)
        True
        >>> M == M1
        False
        >>> M == M2
        True

    `LinearMatroid` instances `M` and `N` satisfy `M == N` if the representations are equivalent up to row operations and column scaling:

    Sage

        sage: M1 = Matroid(groundset='abcd',
        ....:          matrix=Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 2]]))
        sage: M2 = Matroid(groundset='abcd',
        ....:          matrix=Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 3]]))
        sage: M3 = Matroid(groundset='abcd',
        ....:          matrix=Matrix(GF(7), [[2, 6, 1, 0], [6, 1, 0, 1]]))
        sage: M1.equals(M2)
        True
        sage: M1.equals(M3)
        True
        sage: M1 == M2
        False
        sage: M1 == M3
        True
        sage: M1.is_field_equivalent(M2)
        False
        sage: M1.is_field_equivalent(M3)
        True
        sage: M1.is_field_equivalent(M1)
        True

    [Python]

        >>> from sage.all import *
        >>> M1 = Matroid(groundset='abcd',
        ...          matrix=Matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(2)]]))
        >>> M2 = Matroid(groundset='abcd',
        ...          matrix=Matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(3)]]))
        >>> M3 = Matroid(groundset='abcd',
        ...          matrix=Matrix(GF(Integer(7)), [[Integer(2), Integer(6), Integer(1), Integer(0)], [Integer(6), Integer(1), Integer(0), Integer(1)]]))
        >>> M1.equals(M2)
        True
        >>> M1.equals(M3)
        True
        >>> M1 == M2
        False
        >>> M1 == M3
        True
        >>> M1.is_field_equivalent(M2)
        False
        >>> M1.is_field_equivalent(M3)
        True
        >>> M1.is_field_equivalent(M1)
        True

  is_field_isomorphic(other)

    Test isomorphism between matroid representations.

    Two represented matroids are field isomorphic if there is a bijection between their groundsets that induces a field equivalence between their representation matrices: the matrices are equal up to row operations and column scaling. This implies that the matroids are isomorphic, but the converse is false: two isomorphic matroids can be represented by matrices that are not field equivalent.

    INPUT:

    - `other` – matroid

    OUTPUT: boolean

    See also

    `M.is_isomorphic()`, `M.is_field_isomorphism()`, `M.is_field_equivalent()`

    EXAMPLES:

    Sage

        sage: M1 = matroids.Wheel(3)
        sage: M2 = Matroid(graphs.CompleteGraph(4), regular=True)                   # needs sage.graphs
        sage: M1.is_field_isomorphic(M2)                                            # needs sage.graphs
        True
        sage: M3 = Matroid(bases=M1.bases())
        sage: M1.is_field_isomorphic(M3)
        Traceback (most recent call last):
        ...
        AttributeError: 'sage.matroids.basis_matroid.BasisMatroid' object
        has no attribute 'base_ring'...
        sage: from sage.matroids.advanced import *
        sage: M4 = BinaryMatroid(Matrix(M1))
        sage: M5 = LinearMatroid(reduced_matrix=Matrix(GF(2), [[-1, 0, 1],
        ....:                                    [1, -1, 0], [0, 1, -1]]))
        sage: M4.is_field_isomorphic(M5)
        True

        sage: M1 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7),
        ....:                               [[1, 0, 1, 1], [0, 1, 1, 2]]))
        sage: M2 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7),
        ....:                               [[1, 0, 1, 1], [0, 1, 2, 1]]))
        sage: M1.is_field_isomorphic(M2)
        True
        sage: M1.is_field_equivalent(M2)
        False

    Python

        >>> from sage.all import *
        >>> M1 = matroids.Wheel(Integer(3))
        >>> M2 = Matroid(graphs.CompleteGraph(Integer(4)), regular=True)                   # needs sage.graphs
        >>> M1.is_field_isomorphic(M2)                                            # needs sage.graphs
        True
        >>> M3 = Matroid(bases=M1.bases())
        >>> M1.is_field_isomorphic(M3)
        Traceback (most recent call last):
        ...
        AttributeError: 'sage.matroids.basis_matroid.BasisMatroid' object
        has no attribute 'base_ring'...
        >>> from sage.matroids.advanced import *
        >>> M4 = BinaryMatroid(Matrix(M1))
        >>> M5 = LinearMatroid(reduced_matrix=Matrix(GF(Integer(2)), [[-Integer(1), Integer(0), Integer(1)],
        ...                                    [Integer(1), -Integer(1), Integer(0)], [Integer(0), Integer(1), -Integer(1)]]))
        >>> M4.is_field_isomorphic(M5)
        True

        >>> M1 = Matroid(groundset=[Integer(0), Integer(1), Integer(2), Integer(3)], matrix=Matrix(GF(Integer(7)),
        ...                               [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(2)]]))
        >>> M2 = Matroid(groundset=[Integer(0), Integer(1), Integer(2), Integer(3)], matrix=Matrix(GF(Integer(7)),
        ...                               [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(2), Integer(1)]]))
        >>> M1.is_field_isomorphic(M2)
        True
        >>> M1.is_field_equivalent(M2)
        False

  is_field_isomorphism(other, morphism)

    Test if a provided morphism induces a bijection between represented matroids.

    Two represented matroids are field isomorphic if the bijection `morphism` between them induces a field equivalence between their representation matrices: the matrices are equal up to row operations and column scaling. This implies that the matroids are isomorphic, but the converse is false: two isomorphic matroids can be represented by matrices that are not field equivalent.

    INPUT:

    - `other` – matroid

    - `morphism` – a map from the groundset of `self` to the groundset of `other`. See documentation of the `M.is_isomorphism()` method for more on what is accepted as input.

    OUTPUT: boolean

    See also

    `M.is_isomorphism()`, `M.is_field_equivalent()`, `M.is_field_isomorphic()`

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: N = matroids.catalog.NonFano()
        sage: N.is_field_isomorphism(M, {e:e for e in M.groundset()})
        False

        sage: from sage.matroids.advanced import *
        sage: M = matroids.catalog.Fano().delete(['g'])
        sage: N = LinearMatroid(reduced_matrix=Matrix(GF(2),
        ....:                       [[-1, 0, 1], [1, -1, 0], [0, 1, -1]]))
        sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3}
        sage: M.is_field_isomorphism(N, morphism)
        True

        sage: M1 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7),
        ....:                               [[1, 0, 1, 1], [0, 1, 1, 2]]))
        sage: M2 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7),
        ....:                               [[1, 0, 1, 1], [0, 1, 2, 1]]))
        sage: mf1 = {0:0, 1:1, 2:2, 3:3}
        sage: mf2 = {0:0, 1:1, 2:3, 3:2}
        sage: M1.is_field_isomorphism(M2, mf1)
        False
        sage: M1.is_field_isomorphism(M2, mf2)
        True

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> N = matroids.catalog.NonFano()
        >>> N.is_field_isomorphism(M, {e:e for e in M.groundset()})
        False

        >>> from sage.matroids.advanced import *
        >>> M = matroids.catalog.Fano().delete(['g'])
        >>> N = LinearMatroid(reduced_matrix=Matrix(GF(Integer(2)),
        ...                       [[-Integer(1), Integer(0), Integer(1)], [Integer(1), -Integer(1), Integer(0)], [Integer(0), Integer(1), -Integer(1)]]))
        >>> morphism = {'a':Integer(0), 'b':Integer(1), 'c': Integer(2), 'd':Integer(4), 'e':Integer(5), 'f':Integer(3)}
        >>> M.is_field_isomorphism(N, morphism)
        True

        >>> M1 = Matroid(groundset=[Integer(0), Integer(1), Integer(2), Integer(3)], matrix=Matrix(GF(Integer(7)),
        ...                               [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(2)]]))
        >>> M2 = Matroid(groundset=[Integer(0), Integer(1), Integer(2), Integer(3)], matrix=Matrix(GF(Integer(7)),
        ...                               [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(2), Integer(1)]]))
        >>> mf1 = {Integer(0):Integer(0), Integer(1):Integer(1), Integer(2):Integer(2), Integer(3):Integer(3)}
        >>> mf2 = {Integer(0):Integer(0), Integer(1):Integer(1), Integer(2):Integer(3), Integer(3):Integer(2)}
        >>> M1.is_field_isomorphism(M2, mf1)
        False
        >>> M1.is_field_isomorphism(M2, mf2)
        True

  is_valid(certificate=False)

    Test if the data represent an actual matroid.

    Since this matroid is linear, we test the representation matrix.

    INPUT:

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

    OUTPUT: boolean, or (boolean, dictionary)

    The boolean output value is:

    - `True` if the matrix is over a field.

    - `True` if the matrix is over a ring and all cross ratios are invertible.

    - `False` otherwise.

    Note

    This function does NOT test if the cross ratios are contained in the appropriate set of fundamentals. To that end, use

    `M.cross_ratios().issubset(F)`

    where `F` is the set of fundamentals.

    See also

    `M.cross_ratios()`

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=QQ, reduced_matrix=Matrix(ZZ,
        ....:                          [[1, 0, 1], [1, 1, 0], [0, 1, 1]]))
        sage: M.is_valid()
        True
        sage: from sage.matroids.advanced import *  # LinearMatroid
        sage: M = LinearMatroid(ring=ZZ, reduced_matrix=Matrix(ZZ,
        ....:                          [[1, 0, 1], [1, 1, 0], [0, 1, 1]]))
        sage: M.is_valid(certificate=True)
        (False, {'error': 'not all cross ratios are invertible'})

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=QQ, reduced_matrix=Matrix(ZZ,
        ...                          [[Integer(1), Integer(0), Integer(1)], [Integer(1), Integer(1), Integer(0)], [Integer(0), Integer(1), Integer(1)]]))
        >>> M.is_valid()
        True
        >>> from sage.matroids.advanced import *  # LinearMatroid
        >>> M = LinearMatroid(ring=ZZ, reduced_matrix=Matrix(ZZ,
        ...                          [[Integer(1), Integer(0), Integer(1)], [Integer(1), Integer(1), Integer(0)], [Integer(0), Integer(1), Integer(1)]]))
        >>> M.is_valid(certificate=True)
        (False, {'error': 'not all cross ratios are invertible'})

  line_flats()

    Return the lines that define the maximal non-trivial flats of `self`.

    A maximal non-trivial flat is 1 dimensional.

    EXAMPLES:

    Sage

        sage: mat = matrix([[1,0,0,0,1],[0,1,0,1,-1],[0,0,1,0,0]]); mat
        [ 1  0  0  0  1]
        [ 0  1  0  1 -1]
        [ 0  0  1  0  0]
        sage: M = Matroid(mat)
        sage: M.line_flats()
        {frozenset({0, 1, 3, 4}): (0, 0, 1),
         frozenset({0, 2}): (0, 1, 0),
         frozenset({1, 2, 3}): (1, 0, 0),
         frozenset({2, 4}): (1, 1, 0)}

    Python

        >>> from sage.all import *
        >>> mat = matrix([[Integer(1),Integer(0),Integer(0),Integer(0),Integer(1)],[Integer(0),Integer(1),Integer(0),Integer(1),-Integer(1)],[Integer(0),Integer(0),Integer(1),Integer(0),Integer(0)]]); mat
        [ 1  0  0  0  1]
        [ 0  1  0  1 -1]
        [ 0  0  1  0  0]
        >>> M = Matroid(mat)
        >>> M.line_flats()
        {frozenset({0, 1, 3, 4}): (0, 0, 1),
         frozenset({0, 2}): (0, 1, 0),
         frozenset({1, 2, 3}): (1, 0, 0),
         frozenset({2, 4}): (1, 1, 0)}

  linear_coextension(element, cochain=None, row=None)

    Return a linear coextension of this matroid.

    A linear coextension of the represented matroid \(M\) by element \(e\) is a matroid represented by

    \[\begin{split}\begin{bmatrix} A & 0\\ -c & 1 \end{bmatrix},\end{split}\]

    where \(A\) is a representation matrix of \(M\), \(c\) is a new row, and the last column is labeled by \(e\).

    This is the dual method of `M.linear_extension()`.

    INPUT:

    - `element` – the name of the new element

    - `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 groundset to elements of the base ring

    OUTPUT:

    A linear matroid \(N = M([A 0; -c 1])\), where \(A\) is a matrix such that the current matroid is \(M[A]\), and \(c\) is either given by `row` (relative to `self.representation()`) or has nonzero entries given by `cochain`.

    Note

    The minus sign is to ensure this method commutes with dualizing. See the last example.

    See also

    `M.coextension()`, `M.linear_extension()`, `M.dual()`

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0],
        ....:                                 [1, 0, 1, 0, 1, 0],
        ....:                                 [0, 1, 1, 0, 0, 1],
        ....:                                 [0, 0, 0, 1, 1, 1]])
        sage: M.linear_coextension(6, {0:1, 5: 1}).representation()
        [1 1 0 1 0 0 0]
        [1 0 1 0 1 0 0]
        [0 1 1 0 0 1 0]
        [0 0 0 1 1 1 0]
        [1 0 0 0 0 1 1]
        sage: M.linear_coextension(6, row=[0,1,1,1,0,1]).representation()
        [1 1 0 1 0 0 0]
        [1 0 1 0 1 0 0]
        [0 1 1 0 0 1 0]
        [0 0 0 1 1 1 0]
        [0 1 1 1 0 1 1]

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=GF(Integer(2)), matrix=[[Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0)],
        ...                                 [Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(0)],
        ...                                 [Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(1)],
        ...                                 [Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)]])
        >>> M.linear_coextension(Integer(6), {Integer(0):Integer(1), Integer(5): Integer(1)}).representation()
        [1 1 0 1 0 0 0]
        [1 0 1 0 1 0 0]
        [0 1 1 0 0 1 0]
        [0 0 0 1 1 1 0]
        [1 0 0 0 0 1 1]
        >>> M.linear_coextension(Integer(6), row=[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(1)]).representation()
        [1 1 0 1 0 0 0]
        [1 0 1 0 1 0 0]
        [0 1 1 0 0 1 0]
        [0 0 0 1 1 1 0]
        [0 1 1 1 0 1 1]

    Coextending commutes with dualizing:

    Sage

        sage: M = matroids.catalog.NonFano()
        sage: chain = {'a': 1, 'b': -1, 'f': 1}
        sage: M1 = M.linear_coextension('x', chain)
        sage: M2 = M.dual().linear_extension('x', chain)
        sage: M1 == M2.dual()
        True

    [Python]

        >>> from sage.all import *
        >>> M = matroids.catalog.NonFano()
        >>> chain = {'a': Integer(1), 'b': -Integer(1), 'f': Integer(1)}
        >>> M1 = M.linear_coextension('x', chain)
        >>> M2 = M.dual().linear_extension('x', chain)
        >>> M1 == M2.dual()
        True

  linear_coextension_cochains(F=None, cosimple=False, fundamentals=None)

    Create a list of cochains that determine the single-element coextensions of this linear matroid representation.

    A cochain is a dictionary, mapping elements from the groundset to elements of the base ring. If \(A\) represents the current matroid, then the coextension is given by \(N = M([A 0; -c 1])\), with the entries of \(c\) given by the cochain. Note that the matroid does not change when row operations are carried out on \(A\).

    INPUT:

    - `F` – (default: `self.groundset()`) a subset of the groundset

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

    - `fundamentals` – (default: `None`) a set elements of the base ring

    OUTPUT:

    A list of cochains, so each single-element coextension of this linear matroid representation is given by one of these cochains.

    If one or more of the above inputs is given, the list is restricted to chains

    - so that the support of each cochain lies in `F`, if given

    - so that the cochain does not generate a series extension or coloop, if `cosimple = True`

    - so that in the coextension generated by this cochain, the cross ratios are restricted to `fundamentals`, if given.

    See also

    `M.linear_coextension()`, `M.linear_coextensions()`, `M.cross_ratios()`

    EXAMPLES:

    Sage

        sage: M = Matroid(reduced_matrix=Matrix(GF(2),
        ....:                          [[1, 1, 0], [1, 0, 1], [0, 1, 1]]))
        sage: len(M.linear_coextension_cochains())
        8
        sage: len(M.linear_coextension_cochains(F=[0, 1]))
        4
        sage: len(M.linear_coextension_cochains(F=[0, 1], cosimple=True))
        0
        sage: M.linear_coextension_cochains(F=[3, 4, 5], cosimple=True)
        [{3: 1, 4: 1, 5: 1}]
        sage: N = Matroid(ring=QQ,
        ....:         reduced_matrix=[[-1, -1, 0], [1, 0, -1], [0, 1, 1]])
        sage: N.linear_coextension_cochains(F=[0, 1], cosimple=True,
        ....:                           fundamentals=set([1, -1, 1/2, 2]))
        [{0: 2, 1: 1}, {0: -1, 1: 1}, {0: 1/2, 1: 1}]

    Python

        >>> from sage.all import *
        >>> M = Matroid(reduced_matrix=Matrix(GF(Integer(2)),
        ...                          [[Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]))
        >>> len(M.linear_coextension_cochains())
        8
        >>> len(M.linear_coextension_cochains(F=[Integer(0), Integer(1)]))
        4
        >>> len(M.linear_coextension_cochains(F=[Integer(0), Integer(1)], cosimple=True))
        0
        >>> M.linear_coextension_cochains(F=[Integer(3), Integer(4), Integer(5)], cosimple=True)
        [{3: 1, 4: 1, 5: 1}]
        >>> N = Matroid(ring=QQ,
        ...         reduced_matrix=[[-Integer(1), -Integer(1), Integer(0)], [Integer(1), Integer(0), -Integer(1)], [Integer(0), Integer(1), Integer(1)]])
        >>> N.linear_coextension_cochains(F=[Integer(0), Integer(1)], cosimple=True,
        ...                           fundamentals=set([Integer(1), -Integer(1), Integer(1)/Integer(2), Integer(2)]))
        [{0: 2, 1: 1}, {0: -1, 1: 1}, {0: 1/2, 1: 1}]

  linear_coextensions(element=None, F=None, cosimple=False, fundamentals=None)

    Create a list of linear matroids represented by corank-preserving single-element coextensions of this linear matroid representation.

    INPUT:

    - `element` – (default: `None`) the name of the new element of the groundset

    - `F` – (default: `None`) a subset of the groundset

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

    - `fundamentals` – (default: `None`) a set elements of the base ring

    OUTPUT:

    A list of linear matroids represented by corank-preserving single-element coextensions of this linear matroid representation. In particular, the coextension by a loop is not generated.

    If one or more of the above inputs is given, the list is restricted to coextensions

    - so that the new element lies in the cospan of `F`, if given.

    - so that the new element is no coloop and is not in series with another element, if `cosimple = True`.

    - so that in the representation of the coextension, the cross ratios are restricted to `fundamentals`, if given. Note that it is assumed that the cross ratios of the input matroid already satisfy this condition.

    See also

    `M.linear_coextension()`, `M.linear_coextension_cochains()`, `M.cross_ratios()`

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=GF(2),
        ....:         reduced_matrix=[[-1, 0, 1], [1, -1, 0], [0, 1, -1]])
        sage: len(M.linear_coextensions())
        8
        sage: S = M.linear_coextensions(cosimple=True)
        sage: S
        [Binary matroid of rank 4 on 7 elements, type (3, 7)]
        sage: F7 = matroids.catalog.Fano()
        sage: S[0].is_field_isomorphic(F7.dual())
        True
        sage: M = Matroid(ring=QQ,
        ....:            reduced_matrix=[[1, 0, 1], [1, 1, 0], [0, 1, 1]])
        sage: S = M.linear_coextensions(cosimple=True,
        ....:                           fundamentals=[1, -1, 1/2, 2])
        sage: len(S)
        7
        sage: NF7 = matroids.catalog.NonFano()
        sage: any(N.is_isomorphic(NF7.dual()) for N in S)
        True
        sage: len(M.linear_coextensions(cosimple=True,
        ....:                           fundamentals=[1, -1, 1/2, 2],
        ....:                           F=[3, 4]))
        1

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=GF(Integer(2)),
        ...         reduced_matrix=[[-Integer(1), Integer(0), Integer(1)], [Integer(1), -Integer(1), Integer(0)], [Integer(0), Integer(1), -Integer(1)]])
        >>> len(M.linear_coextensions())
        8
        >>> S = M.linear_coextensions(cosimple=True)
        >>> S
        [Binary matroid of rank 4 on 7 elements, type (3, 7)]
        >>> F7 = matroids.catalog.Fano()
        >>> S[Integer(0)].is_field_isomorphic(F7.dual())
        True
        >>> M = Matroid(ring=QQ,
        ...            reduced_matrix=[[Integer(1), Integer(0), Integer(1)], [Integer(1), Integer(1), Integer(0)], [Integer(0), Integer(1), Integer(1)]])
        >>> S = M.linear_coextensions(cosimple=True,
        ...                           fundamentals=[Integer(1), -Integer(1), Integer(1)/Integer(2), Integer(2)])
        >>> len(S)
        7
        >>> NF7 = matroids.catalog.NonFano()
        >>> any(N.is_isomorphic(NF7.dual()) for N in S)
        True
        >>> len(M.linear_coextensions(cosimple=True,
        ...                           fundamentals=[Integer(1), -Integer(1), Integer(1)/Integer(2), Integer(2)],
        ...                           F=[Integer(3), Integer(4)]))
        1

  linear_extension(element, chain=None, col=None)

    Return a linear extension of this matroid.

    A linear extension of the represented matroid \(M\) by element \(e\) is a matroid represented by \([A\ \ b]\), where \(A\) is a representation matrix of \(M\) and \(b\) is a new column labeled by \(e\).

    INPUT:

    - `element` – the name of the new element

    - `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 groundset to elements of the base ring

    OUTPUT:

    A linear matroid \(N = M([A\ \ b])\), where \(A\) is a matrix such that the current matroid is \(M[A]\), and \(b\) is either given by `col` or is a weighted combination of columns of \(A\), the weights being given by `chain`.

    See also

    `M.extension()`.

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0],
        ....:                                 [1, 0, 1, 0, 1, 0],
        ....:                                 [0, 1, 1, 0, 0, 1],
        ....:                                 [0, 0, 0, 1, 1, 1]])
        sage: M.linear_extension(6, {0:1, 5: 1}).representation()
        [1 1 0 1 0 0 1]
        [1 0 1 0 1 0 1]
        [0 1 1 0 0 1 1]
        [0 0 0 1 1 1 1]
        sage: M.linear_extension(6, col=[0, 1, 1, 1]).representation()
        [1 1 0 1 0 0 0]
        [1 0 1 0 1 0 1]
        [0 1 1 0 0 1 1]
        [0 0 0 1 1 1 1]

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=GF(Integer(2)), matrix=[[Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0)],
        ...                                 [Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(0)],
        ...                                 [Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(1)],
        ...                                 [Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)]])
        >>> M.linear_extension(Integer(6), {Integer(0):Integer(1), Integer(5): Integer(1)}).representation()
        [1 1 0 1 0 0 1]
        [1 0 1 0 1 0 1]
        [0 1 1 0 0 1 1]
        [0 0 0 1 1 1 1]
        >>> M.linear_extension(Integer(6), col=[Integer(0), Integer(1), Integer(1), Integer(1)]).representation()
        [1 1 0 1 0 0 0]
        [1 0 1 0 1 0 1]
        [0 1 1 0 0 1 1]
        [0 0 0 1 1 1 1]

  linear_extension_chains(F=None, simple=False, fundamentals=None)

    Create a list of chains that determine the single-element extensions of this linear matroid representation.

    A chain is a dictionary, mapping elements from the groundset to elements of the base ring, indicating a linear combination of columns to form the new column. Think of chains as vectors, only independent of representation.

    INPUT:

    - `F` – (default: `self.groundset()`) a subset of the groundset

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

    - `fundamentals` – (default: `None`) a set elements of the base ring

    OUTPUT:

    A list of chains, so each single-element extension of this linear matroid representation is given by one of these chains.

    If one or more of the above inputs is given, the list is restricted to chains

    - so that the support of each chain lies in `F`, if given

    - so that the chain does not generate a parallel extension or loop, if `simple = True`

    - so that in the extension generated by this chain, the cross ratios are restricted to `fundamentals`, if given.

    See also

    `M.linear_extension()`, `M.linear_extensions()`, `M.cross_ratios()`

    EXAMPLES:

    Sage

        sage: M = Matroid(reduced_matrix=Matrix(GF(2),
        ....:                          [[1, 1, 0], [1, 0, 1], [0, 1, 1]]))
        sage: len(M.linear_extension_chains())
        8
        sage: len(M.linear_extension_chains(F=[0, 1]))
        4
        sage: len(M.linear_extension_chains(F=[0, 1], simple=True))
        0
        sage: M.linear_extension_chains(F=[0, 1, 2], simple=True)
        [{0: 1, 1: 1, 2: 1}]
        sage: N = Matroid(ring=QQ,
        ....:         reduced_matrix=[[-1, -1, 0], [1, 0, -1], [0, 1, 1]])
        sage: L = N.linear_extension_chains(F=[0, 1], simple=True,
        ....:                           fundamentals=set([1, -1, 1/2, 2]))
        sage: result = [{0: 1, 1: 1}, {0: -1/2, 1: 1}, {0: -2, 1: 1}]
        sage: all(D in L for D in result)
        True

    Python

        >>> from sage.all import *
        >>> M = Matroid(reduced_matrix=Matrix(GF(Integer(2)),
        ...                          [[Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]))
        >>> len(M.linear_extension_chains())
        8
        >>> len(M.linear_extension_chains(F=[Integer(0), Integer(1)]))
        4
        >>> len(M.linear_extension_chains(F=[Integer(0), Integer(1)], simple=True))
        0
        >>> M.linear_extension_chains(F=[Integer(0), Integer(1), Integer(2)], simple=True)
        [{0: 1, 1: 1, 2: 1}]
        >>> N = Matroid(ring=QQ,
        ...         reduced_matrix=[[-Integer(1), -Integer(1), Integer(0)], [Integer(1), Integer(0), -Integer(1)], [Integer(0), Integer(1), Integer(1)]])
        >>> L = N.linear_extension_chains(F=[Integer(0), Integer(1)], simple=True,
        ...                           fundamentals=set([Integer(1), -Integer(1), Integer(1)/Integer(2), Integer(2)]))
        >>> result = [{Integer(0): Integer(1), Integer(1): Integer(1)}, {Integer(0): -Integer(1)/Integer(2), Integer(1): Integer(1)}, {Integer(0): -Integer(2), Integer(1): Integer(1)}]
        >>> all(D in L for D in result)
        True

  linear_extensions(element=None, F=None, simple=False, fundamentals=None)

    Create a list of linear matroids represented by rank-preserving single-element extensions of this linear matroid representation.

    INPUT:

    - `element` – (default: `None`) the name of the new element of the groundset

    - `F` – (default: `None`) a subset of the groundset

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

    - `fundamentals` – (default: `None`) a set elements of the base ring

    OUTPUT:

    A list of linear matroids represented by rank-preserving single-element extensions of this linear matroid representation. In particular, the extension by a coloop is not generated.

    If one or more of the above inputs is given, the list is restricted to matroids

    - so that the new element is spanned by `F`, if given

    - so that the new element is not a loop or in a parallel pair, if `simple=True`

    - so that in the representation of the extension, the cross ratios are restricted to `fundamentals`, if given. Note that it is assumed that the cross ratios of the input matroid already satisfy this condition.

    See also

    `M.linear_extension()`, `M.linear_extension_chains()`, `M.cross_ratios()`

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=GF(2),
        ....:             reduced_matrix=[[-1, 0, 1], [1, -1, 0], [0, 1, -1]])
        sage: len(M.linear_extensions())
        8
        sage: S = M.linear_extensions(simple=True); S
        [Binary matroid of rank 3 on 7 elements, type (3, 0)]
        sage: S[0].is_field_isomorphic(matroids.catalog.Fano())
        True
        sage: M = Matroid(ring=QQ,
        ....:             reduced_matrix=[[1, 0, 1], [1, 1, 0], [0, 1, 1]])
        sage: S = M.linear_extensions(simple=True,
        ....:                         fundamentals=[1, -1, 1/2, 2])
        sage: len(S)
        7
        sage: any(N.is_isomorphic(matroids.catalog.NonFano())
        ....:     for N in S)
        True
        sage: len(M.linear_extensions(simple=True,
        ....:                         fundamentals=[1, -1, 1/2, 2], F=[0, 1]))
        1

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=GF(Integer(2)),
        ...             reduced_matrix=[[-Integer(1), Integer(0), Integer(1)], [Integer(1), -Integer(1), Integer(0)], [Integer(0), Integer(1), -Integer(1)]])
        >>> len(M.linear_extensions())
        8
        >>> S = M.linear_extensions(simple=True); S
        [Binary matroid of rank 3 on 7 elements, type (3, 0)]
        >>> S[Integer(0)].is_field_isomorphic(matroids.catalog.Fano())
        True
        >>> M = Matroid(ring=QQ,
        ...             reduced_matrix=[[Integer(1), Integer(0), Integer(1)], [Integer(1), Integer(1), Integer(0)], [Integer(0), Integer(1), Integer(1)]])
        >>> S = M.linear_extensions(simple=True,
        ...                         fundamentals=[Integer(1), -Integer(1), Integer(1)/Integer(2), Integer(2)])
        >>> len(S)
        7
        >>> any(N.is_isomorphic(matroids.catalog.NonFano())
        ...     for N in S)
        True
        >>> len(M.linear_extensions(simple=True,
        ...                         fundamentals=[Integer(1), -Integer(1), Integer(1)/Integer(2), Integer(2)], F=[Integer(0), Integer(1)]))
        1

  orlik_terao_algebra(R=None, ordering=None, **kwargs)

    Return the Orlik-Terao algebra of `self`.

    INPUT:

    - `R` – (default: the base ring of `self`) the base ring

    - `ordering` – (optional) an ordering of the groundset

    See also

    `OrlikTeraoAlgebra`

    EXAMPLES:

    Sage

        sage: M = matroids.Wheel(3)
        sage: OS = M.orlik_terao_algebra(); OS
        Orlik-Terao algebra of Wheel(3):
         Regular matroid of rank 3 on 6 elements with 16 bases
         over Integer Ring
        sage: OS.base_ring()
        Integer Ring
        sage: M.orlik_terao_algebra(QQ).base_ring()
        Rational Field

        sage: G = SymmetricGroup(3);                                                # needs sage.groups
        sage: OTG = M.orlik_terao_algebra(QQ, invariant=G)                          # needs sage.groups

        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 is OTG2
        True

    Python

        >>> from sage.all import *
        >>> M = matroids.Wheel(Integer(3))
        >>> OS = M.orlik_terao_algebra(); OS
        Orlik-Terao algebra of Wheel(3):
         Regular matroid of rank 3 on 6 elements with 16 bases
         over Integer Ring
        >>> OS.base_ring()
        Integer Ring
        >>> M.orlik_terao_algebra(QQ).base_ring()
        Rational Field

        >>> G = SymmetricGroup(Integer(3));                                                # needs sage.groups
        >>> OTG = M.orlik_terao_algebra(QQ, invariant=G)                          # needs sage.groups

        >>> # needs sage.groups
        >>> G = SymmetricGroup(Integer(4))
        >>> action = lambda g, x: g(x + Integer(1)) - Integer(1)
        >>> OTG1 = M.orlik_terao_algebra(QQ, invariant=(G, action))
        >>> OTG2 = M.orlik_terao_algebra(QQ, invariant=(action, G))
        >>> OTG1 is OTG2
        True

  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: M = matroids.catalog.Fano()
        sage: sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        sage: N = M.relabel({'g': 'x'})
        sage: sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        >>> N = M.relabel({'g': 'x'})
        >>> sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

  representation(B=None, reduced=False, labels=None, order=None, lift_map=None)

    Return a matrix representing the matroid.

    Let \(M\) be a matroid on \(n\) elements with rank \(r\). Let \(E\) be an ordering of the groundset, as output by `M.groundset_list()`. A representation of the matroid is an \(r \times n\) matrix with the following property. Consider column \(i\) to be labeled by \(E[i]\), and denote by \(A[F]\) the submatrix formed by the columns labeled by the subset \(F \subseteq E\). Then for all \(F \subseteq E\), the columns of \(A[F]\) are linearly independent if and only if \(F\) is an independent set in the matroid.

    A reduced representation is a matrix \(D\) such that \([I\ \ D]\) is a representation of the matroid, where \(I\) is an \(r \times r\) identity matrix. In this case, the rows of \(D\) are considered to be labeled by the first \(r\) elements of the list `E`, and the columns by the remaining \(n - r\) elements.

    INPUT:

    - `B` – (default: `None`) a subset of elements. When provided, the representation is such that a basis \(B'\) that maximally intersects \(B\) is an identity matrix.

    - `reduced` – boolean (default: `False`); when `True`, return a reduced matrix \(D\) (so \([I\ \ D]\) is a representation of the matroid). Otherwise return a full representation matrix.

    - `labels` – (default: `None`) when `True`, return additionally a list of column labels (if `reduced=False`) or a list of row labels and a list of column labels (if `reduced=True`). The default setting, `None`, will not return the labels for a full matrix, but will return the labels for a reduced matrix.

    - `order` – sequence or `None` or `True` (default: `None`)

      - when a sequence, it should be an ordering of the groundset elements, and the columns (and, in case of a reduced representation, rows) will be presented in the given order,

      - when `None`, use the same ordering that `groundset_list()` uses,

      - when `True`, return a morphism of free modules instead of a matrix.

    - `lift_map` – (default: `None`) a dictionary containing the cross ratios of the representing matrix in its domain. If provided, the representation will be transformed by mapping its cross ratios according to `lift_map`.

    OUTPUT:

    - `A` – a full or reduced representation matrix of `self`; or

    - `(A, E)` – a full representation matrix `A` and a list `E` of column labels; or

    - `(A, R, C)` – a reduced representation matrix and a list `R` of row labels and a list `C` of column labels

    If `B == None` and `reduced == False` and `order == None` then this method will always output the same matrix (except when `M._forget()` is called): either the matrix used as input to create the matroid, or a matrix in which the lexicographically least basis corresponds to an identity. If only `order` is not `None`, the columns of this matrix will be permuted accordingly.

    If a `lift_map` is provided, then the resulting matrix will be lifted using the method `lift_cross_ratios()` See the docstring of this method for further details.

    Note

    A shortcut for `M.representation()` is `Matrix(M)`.

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: M.representation()
        [1 0 0 0 1 1 1]
        [0 1 0 1 0 1 1]
        [0 0 1 1 1 0 1]
        sage: Matrix(M) == M.representation()
        True
        sage: M.representation(labels=True)
        (
        [1 0 0 0 1 1 1]
        [0 1 0 1 0 1 1]
        [0 0 1 1 1 0 1], ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        )
        sage: M.representation(B='efg')
        [1 1 0 1 1 0 0]
        [1 0 1 1 0 1 0]
        [1 1 1 0 0 0 1]
        sage: M.representation(B='efg', order='efgabcd')
        [1 0 0 1 1 0 1]
        [0 1 0 1 0 1 1]
        [0 0 1 1 1 1 0]
        sage: M.representation(B='abc', reduced=True)
        (
        [0 1 1 1]
        [1 0 1 1]
        [1 1 0 1], ['a', 'b', 'c'], ['d', 'e', 'f', 'g']
        )
        sage: M.representation(B='efg', reduced=True, labels=False,
        ....:                  order='gfeabcd')
        [1 1 1 0]
        [1 0 1 1]
        [1 1 0 1]

        sage: from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid
        sage: R = GF(7)
        sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]])
        sage: M = LinearMatroid(reduced_matrix=A)
        sage: M.representation(lift_map=lift_map('sru'))                            # needs sage.rings.finite_rings
        [     1      0      0      1      0      1      1      1]
        [     0      1      0 -z + 1      1      0      0      1]
        [     0      0      1      0      1      -1 z - 1      0]

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> M.representation()
        [1 0 0 0 1 1 1]
        [0 1 0 1 0 1 1]
        [0 0 1 1 1 0 1]
        >>> Matrix(M) == M.representation()
        True
        >>> M.representation(labels=True)
        (
        [1 0 0 0 1 1 1]
        [0 1 0 1 0 1 1]
        [0 0 1 1 1 0 1], ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        )
        >>> M.representation(B='efg')
        [1 1 0 1 1 0 0]
        [1 0 1 1 0 1 0]
        [1 1 1 0 0 0 1]
        >>> M.representation(B='efg', order='efgabcd')
        [1 0 0 1 1 0 1]
        [0 1 0 1 0 1 1]
        [0 0 1 1 1 1 0]
        >>> M.representation(B='abc', reduced=True)
        (
        [0 1 1 1]
        [1 0 1 1]
        [1 1 0 1], ['a', 'b', 'c'], ['d', 'e', 'f', 'g']
        )
        >>> M.representation(B='efg', reduced=True, labels=False,
        ...                  order='gfeabcd')
        [1 1 1 0]
        [1 0 1 1]
        [1 1 0 1]

        >>> from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid
        >>> R = GF(Integer(7))
        >>> A = Matrix(R, [[Integer(1), Integer(0), Integer(6), Integer(1), Integer(2)],[Integer(6), Integer(1), Integer(0), Integer(0), Integer(1)],[Integer(0), Integer(6), Integer(3), Integer(6), Integer(0)]])
        >>> M = LinearMatroid(reduced_matrix=A)
        >>> M.representation(lift_map=lift_map('sru'))                            # needs sage.rings.finite_rings
        [     1      0      0      1      0      1      1      1]
        [     0      1      0 -z + 1      1      0      0      1]
        [     0      0      1      0      1      -1 z - 1      0]

    As morphisms:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: A = M.representation(order=True); A
        Generic morphism:
         From: Free module generated by {'a', 'b', 'c', 'd', 'e', 'f', 'g'}
               over Finite Field of size 2
         To:   Free module generated by {0, 1, 2} over Finite Field of size 2
        sage: print(A._unicode_art_matrix())
          a b c d e f g
        0⎛1 0 0 0 1 1 1⎞
        1⎜0 1 0 1 0 1 1⎟
        2⎝0 0 1 1 1 0 1⎠
        sage: A = M.representation(B='efg', order=True); A
        Generic morphism:
         From: Free module generated by {'a', 'b', 'c', 'd', 'e', 'f', 'g'}
               over Finite Field of size 2
         To:   Free module generated by {0, 1, 2} over Finite Field of size 2
        sage: print(A._unicode_art_matrix())
          a b c d e f g
        0⎛1 1 0 1 1 0 0⎞
        1⎜1 0 1 1 0 1 0⎟
        2⎝1 1 1 0 0 0 1⎠
        sage: A = M.representation(B='abc', order=True, reduced=True); A
        Generic morphism:
         From: Free module generated by {'d', 'e', 'f', 'g'}
               over Finite Field of size 2
         To:   Free module generated by {'a', 'b', 'c'} over Finite Field of size 2
        sage: print(A._unicode_art_matrix())
          d e f g
        a⎛0 1 1 1⎞
        b⎜1 0 1 1⎟
        c⎝1 1 0 1⎠

    [Python]

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> A = M.representation(order=True); A
        Generic morphism:
         From: Free module generated by {'a', 'b', 'c', 'd', 'e', 'f', 'g'}
               over Finite Field of size 2
         To:   Free module generated by {0, 1, 2} over Finite Field of size 2
        >>> print(A._unicode_art_matrix())
          a b c d e f g
        0⎛1 0 0 0 1 1 1⎞
        1⎜0 1 0 1 0 1 1⎟
        2⎝0 0 1 1 1 0 1⎠
        >>> A = M.representation(B='efg', order=True); A
        Generic morphism:
         From: Free module generated by {'a', 'b', 'c', 'd', 'e', 'f', 'g'}
               over Finite Field of size 2
         To:   Free module generated by {0, 1, 2} over Finite Field of size 2
        >>> print(A._unicode_art_matrix())
          a b c d e f g
        0⎛1 1 0 1 1 0 0⎞
        1⎜1 0 1 1 0 1 0⎟
        2⎝1 1 1 0 0 0 1⎠
        >>> A = M.representation(B='abc', order=True, reduced=True); A
        Generic morphism:
         From: Free module generated by {'d', 'e', 'f', 'g'}
               over Finite Field of size 2
         To:   Free module generated by {'a', 'b', 'c'} over Finite Field of size 2
        >>> print(A._unicode_art_matrix())
          d e f g
        a⎛0 1 1 1⎞
        b⎜1 0 1 1⎟
        c⎝1 1 0 1⎠

  representation_vectors()

    Return a dictionary that associates a column vector with each element of the matroid.

    See also

    `M.representation()`

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Fano()
        sage: E = M.groundset_list()
        sage: [M.representation_vectors()[e] for e in E]
        [(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 1), (1, 0, 1), (1, 1, 0),
         (1, 1, 1)]

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Fano()
        >>> E = M.groundset_list()
        >>> [M.representation_vectors()[e] for e in E]
        [(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 1), (1, 0, 1), (1, 1, 0),
         (1, 1, 1)]

  zonotopal_algebra(k, lines=False, base_ring=None)

    Return the `k`-zonotopal algebra of `self` over `base_ring` containing the ground field of `self`.

    Let \(M\) be a linear matroid with representation matrix \(\overline{M}\) over the field \(R\). Let \(\rho_M(v)\) equal the number of column vectors \(w\) of \(\overline{M}\) such that \(v \cdot w \neq 0\) (that is, \(v\) is not contained in the hyperplane defined by \(w\)). Define an ideal

    \[I_k(M) := \langle v^{\rho_M(v)+k+1} \mid v \in V, v \neq 0 \rangle,\]

    where \(V\) is the column space of \(\overline{M}\). The \(k\)-zonotopal algebra is defined as the quotient \(Z_k(M) := S[e_0, \ldots, e_{m-1}] / I_k(M)\), where \(S\) is any commutative ring containing \(R\).

    The line zonotopal algebra is the quotient of the ideal \(I'_k(M)\) generated by the `line_flats()` rather than all nonzero vectors in \(V\). When \(k \leq 0\), this ideal is equal to \(I_k(M)\) by Lemma 1 of [AP2015].

    INPUT:

    - `k` – integer

    - `lines` – (default: `False`) boolean; if `True`, return the line zonotopal algebra

    See also

    - `central_zonotopal_algebra()`

    - `internal_zonotopal_algebra()`

    EXAMPLES:

    We construct Example 4.1 in [AP2010]:

    Sage

        sage: mat = matrix([[1,0,0,0,1],[0,1,0,1,-1],[0,0,1,0,0]]); mat
        [ 1  0  0  0  1]
        [ 0  1  0  1 -1]
        [ 0  0  1  0  0]
        sage: M = Matroid(mat)
        sage: Z0 = M.zonotopal_algebra(0)
        sage: Z0.defining_ideal().gens()
        [e2^2, e1^4, e0^3, e0^4 + 4*e0^3*e1 + 6*e0^2*e1^2 + 4*e0*e1^3 + e1^4]
        sage: Z0.defining_ideal().gens()[-1].factor()
        (e0 + e1)^4
        sage: Z0.defining_ideal().hilbert_series()
        t^5 + 4*t^4 + 6*t^3 + 5*t^2 + 3*t + 1
        sage: R.<t> = PolynomialRing(ZZ)
        sage: t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(1+t, ~t)
        t^5 + 4*t^4 + 6*t^3 + 5*t^2 + 3*t + 1

        sage: Z1 = M.zonotopal_algebra(-1)
        sage: Z1.defining_ideal().hilbert_series()
        2*t^2 + 2*t + 1
        sage: t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(1, ~t)
        2*t^2 + 2*t + 1

        sage: Z2 = M.zonotopal_algebra(-2)
        sage: Z2.defining_ideal().hilbert_series()
        0
        sage: Z2p = M.internal_zonotopal_algebra()
        sage: Z2p.defining_ideal().hilbert_series()
        0
        sage: t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(0, ~t)
        0

    Python

        >>> from sage.all import *
        >>> mat = matrix([[Integer(1),Integer(0),Integer(0),Integer(0),Integer(1)],[Integer(0),Integer(1),Integer(0),Integer(1),-Integer(1)],[Integer(0),Integer(0),Integer(1),Integer(0),Integer(0)]]); mat
        [ 1  0  0  0  1]
        [ 0  1  0  1 -1]
        [ 0  0  1  0  0]
        >>> M = Matroid(mat)
        >>> Z0 = M.zonotopal_algebra(Integer(0))
        >>> Z0.defining_ideal().gens()
        [e2^2, e1^4, e0^3, e0^4 + 4*e0^3*e1 + 6*e0^2*e1^2 + 4*e0*e1^3 + e1^4]
        >>> Z0.defining_ideal().gens()[-Integer(1)].factor()
        (e0 + e1)^4
        >>> Z0.defining_ideal().hilbert_series()
        t^5 + 4*t^4 + 6*t^3 + 5*t^2 + 3*t + 1
        >>> R = PolynomialRing(ZZ, names=('t',)); (t,) = R._first_ngens(1)
        >>> t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(Integer(1)+t, ~t)
        t^5 + 4*t^4 + 6*t^3 + 5*t^2 + 3*t + 1

        >>> Z1 = M.zonotopal_algebra(-Integer(1))
        >>> Z1.defining_ideal().hilbert_series()
        2*t^2 + 2*t + 1
        >>> t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(Integer(1), ~t)
        2*t^2 + 2*t + 1

        >>> Z2 = M.zonotopal_algebra(-Integer(2))
        >>> Z2.defining_ideal().hilbert_series()
        0
        >>> Z2p = M.internal_zonotopal_algebra()
        >>> Z2p.defining_ideal().hilbert_series()
        0
        >>> t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(Integer(0), ~t)
        0

    We construct the ideal in the proof of Proposition 2 in [AP2015]:

    Sage

        sage: mat = matrix([[1,0,0,1,0,0],[0,1,0,0,1,0],[0,0,1,0,0,1],
        ....:               [0,0,0,-1,-1,-1]]); mat
        [ 1  0  0  1  0  0]
        [ 0  1  0  0  1  0]
        [ 0  0  1  0  0  1]
        [ 0  0  0 -1 -1 -1]
        sage: M = Matroid(mat)
        sage: Z2 = M.zonotopal_algebra(-2)
        sage: Z2.defining_ideal().hilbert_series()
        t + 1
        sage: Z2.defining_ideal().groebner_basis()
        [e3^2, e0, e1, e2]
        sage: Z2p = M.internal_zonotopal_algebra()
        sage: Z2p.defining_ideal().hilbert_series()
        t + 1
        sage: t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(0, ~t)
        t + 1

    [Python]

        >>> from sage.all import *
        >>> mat = matrix([[Integer(1),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(0)],[Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(1)],
        ...               [Integer(0),Integer(0),Integer(0),-Integer(1),-Integer(1),-Integer(1)]]); mat
        [ 1  0  0  1  0  0]
        [ 0  1  0  0  1  0]
        [ 0  0  1  0  0  1]
        [ 0  0  0 -1 -1 -1]
        >>> M = Matroid(mat)
        >>> Z2 = M.zonotopal_algebra(-Integer(2))
        >>> Z2.defining_ideal().hilbert_series()
        t + 1
        >>> Z2.defining_ideal().groebner_basis()
        [e3^2, e0, e1, e2]
        >>> Z2p = M.internal_zonotopal_algebra()
        >>> Z2p.defining_ideal().hilbert_series()
        t + 1
        >>> t**(len(M.groundset())-M.rank()) * M.tutte_polynomial(Integer(0), ~t)
        t + 1

    We use Hilbert series and Theorem 4.12 in [AP2010] to show for \(k > 0\) that the line zonotopal algebra is bigger than the zonotopal algebra (as the line ideal is smaller):

    Sage

        sage: mat = matrix([[1,0], [0,1]])
        sage: M = Matroid(mat)
        sage: n = len(M.groundset())
        sage: r = M.rank()
        sage: m = mat.nrows() - r
        sage: R.<t> = PolynomialRing(ZZ)
        sage: L.<z> = LazyPowerSeriesRing(R.fraction_field())
        sage: H = t^(n-r) / ((1-z) * (1-t*z)^m) * M.tutte_polynomial(1+t/(1-t*z), ~t)
        sage: H[:4]
        [t^2 + 2*t + 1,
         2*t^3 + 3*t^2 + 2*t + 1,
         3*t^4 + 4*t^3 + 3*t^2 + 2*t + 1,
         4*t^5 + 5*t^4 + 4*t^3 + 3*t^2 + 2*t + 1]
        sage: [M.zonotopal_algebra(k, True).defining_ideal().hilbert_series() for k in range(4)]
        [t^2 + 2*t + 1,
         t^4 + 2*t^3 + 3*t^2 + 2*t + 1,
         t^6 + 2*t^5 + 3*t^4 + 4*t^3 + 3*t^2 + 2*t + 1,
         t^8 + 2*t^7 + 3*t^6 + 4*t^5 + 5*t^4 + 4*t^3 + 3*t^2 + 2*t + 1]

    Python

        >>> from sage.all import *
        >>> mat = matrix([[Integer(1),Integer(0)], [Integer(0),Integer(1)]])
        >>> M = Matroid(mat)
        >>> n = len(M.groundset())
        >>> r = M.rank()
        >>> m = mat.nrows() - r
        >>> R = PolynomialRing(ZZ, names=('t',)); (t,) = R._first_ngens(1)
        >>> L = LazyPowerSeriesRing(R.fraction_field(), names=('z',)); (z,) = L._first_ngens(1)
        >>> H = t**(n-r) / ((Integer(1)-z) * (Integer(1)-t*z)**m) * M.tutte_polynomial(Integer(1)+t/(Integer(1)-t*z), ~t)
        >>> H[:Integer(4)]
        [t^2 + 2*t + 1,
         2*t^3 + 3*t^2 + 2*t + 1,
         3*t^4 + 4*t^3 + 3*t^2 + 2*t + 1,
         4*t^5 + 5*t^4 + 4*t^3 + 3*t^2 + 2*t + 1]
        >>> [M.zonotopal_algebra(k, True).defining_ideal().hilbert_series() for k in range(Integer(4))]
        [t^2 + 2*t + 1,
         t^4 + 2*t^3 + 3*t^2 + 2*t + 1,
         t^6 + 2*t^5 + 3*t^4 + 4*t^3 + 3*t^2 + 2*t + 1,
         t^8 + 2*t^7 + 3*t^6 + 4*t^5 + 5*t^4 + 4*t^3 + 3*t^2 + 2*t + 1]

    We finish by verifying Theorem 4.12 in [AP2010] by using Example 4.2 in [AP2010]:

    Sage

        sage: S.<x1,x2> = PolynomialRing(QQ)
        sage: [S.ideal([x1^(k+2), x2^(k+2)]
        ....:          + [(x1+a*x2)^(k+3) for a in range(1,k+5)]
        ....:         ).hilbert_series()
        ....:  for k in range(-2, 4)]
        [0,
         1,
         t^2 + 2*t + 1,
         2*t^3 + 3*t^2 + 2*t + 1,
         3*t^4 + 4*t^3 + 3*t^2 + 2*t + 1,
         4*t^5 + 5*t^4 + 4*t^3 + 3*t^2 + 2*t + 1]

        sage: M.zonotopal_algebra(-2).defining_ideal().hilbert_series()
        0
        sage: M.zonotopal_algebra(-1).defining_ideal().hilbert_series()
        1

    [Python]

        >>> from sage.all import *
        >>> S = PolynomialRing(QQ, names=('x1', 'x2',)); (x1, x2,) = S._first_ngens(2)
        >>> [S.ideal([x1**(k+Integer(2)), x2**(k+Integer(2))]
        ...          + [(x1+a*x2)**(k+Integer(3)) for a in range(Integer(1),k+Integer(5))]
        ...         ).hilbert_series()
        ...  for k in range(-Integer(2), Integer(4))]
        [0,
         1,
         t^2 + 2*t + 1,
         2*t^3 + 3*t^2 + 2*t + 1,
         3*t^4 + 4*t^3 + 3*t^2 + 2*t + 1,
         4*t^5 + 5*t^4 + 4*t^3 + 3*t^2 + 2*t + 1]

        >>> M.zonotopal_algebra(-Integer(2)).defining_ideal().hilbert_series()
        0
        >>> M.zonotopal_algebra(-Integer(1)).defining_ideal().hilbert_series()
        1

    REFERENCES:

    - [AP2010]

    - [AP2015]

class sage.matroids.linear_matroid.QuaternaryMatroid

  Bases: `LinearMatroid`

  Quaternary matroids.

  A quaternary matroid is a linear matroid represented over the finite field with four elements. See `LinearMatroid` for a definition.

  The simplest way to create a `QuaternaryMatroid` is by giving only a matrix \(A\). Then, the groundset defaults to `range(A.ncols())`. Any iterable object \(E\) can be given as a groundset. If \(E\) is a list, then `E[i]` will label the \(i\)-th column of \(A\). Another possibility is to specify a ‘reduced’ matrix \(B\), to create the matroid induced by \(A = [I\ \ B]\).

  INPUT:

  - `matrix` – (default: `None`) a matrix whose column vectors represent the matroid.

  - `reduced_matrix` – (default: `None`) a matrix \(B\) such that \([I\ \ B]\) represents the matroid, where \(I\) is an identity matrix with the same number of rows as \(B\). Only one of `matrix` and `reduced_matrix` should be provided.

  - `groundset` – (default: `None`) an iterable containing the element labels. When provided, must have the correct number of elements: the number of columns of `matrix` or the number of rows plus the number of columns of `reduced_matrix`.

  - `ring` – (default: `None`) must be a copy of \(\GF{4}\)

  - `keep_initial_representation` – boolean (default: `True`); decides whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy.

  - `basis` – (default: `None`) when provided, this is an ordered subset of `groundset`, such that the submatrix of `matrix` indexed by `basis` is an identity matrix. In this case, no row reduction takes place in the initialization phase.

  OUTPUT: a `QuaternaryMatroid` instance based on the data above

  Note

  The recommended way to generate a quaternary matroid is through the `Matroid()` function. This is usually the preferred way, since it automatically chooses between `QuaternaryMatroid` and other classes. For direct access to the `QuaternaryMatroid` constructor, run:

  Sage

      sage: from sage.matroids.advanced import *

  Python

      >>> from sage.all import *
      >>> from sage.matroids.advanced import *

  EXAMPLES:

  Sage

      sage: # needs sage.rings.finite_rings
      sage: GF4 = GF(4, 'x')
      sage: x = GF4.gens()[0]
      sage: A = Matrix(GF4, 2, 4, [[1, 0, 1, 1], [0, 1, 1, x]])
      sage: M = Matroid(A)
      sage: M
      Quaternary matroid of rank 2 on 4 elements
      sage: sorted(M.groundset())
      [0, 1, 2, 3]
      sage: Matrix(M)
      [1 0 1 1]
      [0 1 1 x]
      sage: M = Matroid(matrix=A, groundset='abcd')
      sage: sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      sage: GF4p = GF(4, 'y')
      sage: y = GF4p.gens()[0]
      sage: B = Matrix(GF4p, 2, 2, [[1, 1], [1, y]])
      sage: N = Matroid(reduced_matrix=B, groundset='abcd')
      sage: M == N
      False

  Python

      >>> from sage.all import *
      >>> # needs sage.rings.finite_rings
      >>> GF4 = GF(Integer(4), 'x')
      >>> x = GF4.gens()[Integer(0)]
      >>> A = Matrix(GF4, Integer(2), Integer(4), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), x]])
      >>> M = Matroid(A)
      >>> M
      Quaternary matroid of rank 2 on 4 elements
      >>> sorted(M.groundset())
      [0, 1, 2, 3]
      >>> Matrix(M)
      [1 0 1 1]
      [0 1 1 x]
      >>> M = Matroid(matrix=A, groundset='abcd')
      >>> sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      >>> GF4p = GF(Integer(4), 'y')
      >>> y = GF4p.gens()[Integer(0)]
      >>> B = Matrix(GF4p, Integer(2), Integer(2), [[Integer(1), Integer(1)], [Integer(1), y]])
      >>> N = Matroid(reduced_matrix=B, groundset='abcd')
      >>> M == N
      False

  base_ring()

    Return the base ring of the matrix representing the matroid, in this case \(\GF{4}\).

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=GF(4, 'y'), reduced_matrix=[[1, 0, 1],               # needs sage.rings.finite_rings
        ....:                                              [0, 1, 1]])
        sage: M.base_ring()                                                         # needs sage.rings.finite_rings
        Finite Field in y of size 2^2

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=GF(Integer(4), 'y'), reduced_matrix=[[Integer(1), Integer(0), Integer(1)],               # needs sage.rings.finite_rings
        ...                                              [Integer(0), Integer(1), Integer(1)]])
        >>> M.base_ring()                                                         # needs sage.rings.finite_rings
        Finite Field in y of size 2^2

  bicycle_dimension()

    Return the bicycle dimension of the quaternary matroid.

    The bicycle dimension of a linear subspace \(V\) is \(\dim(V\cap V^\perp)\). We use the inner product \(< v, w >=v_1 w_1^* + ... + v_n w_n^*\), where \(w_i^*\) is obtained from \(w_i\) by applying the unique nontrivial field automorphism of \(\GF{4}\).

    The bicycle dimension of a matroid equals the bicycle dimension of its rowspace, and is a matroid invariant. See [Pen2012].

    OUTPUT: integer

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.Q10()                                            # needs sage.rings.finite_rings
        sage: M.bicycle_dimension()                                                 # needs sage.rings.finite_rings
        0

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.Q10()                                            # needs sage.rings.finite_rings
        >>> M.bicycle_dimension()                                                 # needs sage.rings.finite_rings
        0

  characteristic()

    Return the characteristic of the base ring of the matrix representing the matroid, in this case \(2\).

    EXAMPLES:

    Sage

        sage: M = Matroid(ring=GF(4, 'y'), reduced_matrix=[[1, 0, 1],               # needs sage.rings.finite_rings
        ....:                                              [0, 1, 1]])
        sage: M.characteristic()                                                    # needs sage.rings.finite_rings
        2

    Python

        >>> from sage.all import *
        >>> M = Matroid(ring=GF(Integer(4), 'y'), reduced_matrix=[[Integer(1), Integer(0), Integer(1)],               # needs sage.rings.finite_rings
        ...                                              [Integer(0), Integer(1), Integer(1)]])
        >>> M.characteristic()                                                    # needs sage.rings.finite_rings
        2

  is_valid(certificate=False)

    Test if the data obey the matroid axioms.

    Since this is a linear matroid over the field \(\GF{4}\), this is always the case.

    INPUT:

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

    OUTPUT: `True`, or `(True, {})`

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(4, 'x'), [[]]))                                 # needs sage.rings.finite_rings
        sage: M.is_valid()                                                          # needs sage.rings.finite_rings
        True

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(4), 'x'), [[]]))                                 # needs sage.rings.finite_rings
        >>> M.is_valid()                                                          # needs sage.rings.finite_rings
        True

  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: M = matroids.catalog.RelaxedNonFano("abcdefg")
        sage: sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        sage: N = M.relabel({'g':'x'})
        sage: sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.RelaxedNonFano("abcdefg")
        >>> sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        >>> N = M.relabel({'g':'x'})
        >>> sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

class sage.matroids.linear_matroid.RegularMatroid

  Bases: `LinearMatroid`

  Regular matroids.

  A regular matroid is a linear matroid represented over the integers by a totally unimodular matrix.

  The simplest way to create a `RegularMatroid` is by giving only a matrix \(A\). Then, the groundset defaults to `range(A.ncols())`. Any iterable object \(E\) can be given as a groundset. If \(E\) is a list, then `E[i]` will label the \(i\)-th column of \(A\). Another possibility is to specify a ‘reduced’ matrix \(B\), to create the matroid induced by \(A = [ I B ]\).

  INPUT:

  - `matrix` – (default: `None`) a matrix whose column vectors represent the matroid.

  - `reduced_matrix` – (default: `None`) a matrix \(B\) such that \([I\ \ B]\) represents the matroid, where \(I\) is an identity matrix with the same number of rows as \(B\). Only one of `matrix` and `reduced_matrix` should be provided.

  - `groundset` – (default: `None`) an iterable containing the element labels. When provided, must have the correct number of elements: the number of columns of `matrix` or the number of rows plus the number of columns of `reduced_matrix`.

  - `ring` – (default: `None`) ignored

  - `keep_initial_representation` – boolean (default: `True`); decides whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy.

  - `basis` – (default: `None`) when provided, this is an ordered subset of `groundset`, such that the submatrix of `matrix` indexed by `basis` is an identity matrix. In this case, no row reduction takes place in the initialization phase.

  OUTPUT: a `RegularMatroid` instance based on the data above

  Note

  The recommended way to generate a regular matroid is through the `Matroid()` function. This is usually the preferred way, since it automatically chooses between `RegularMatroid` and other classes. Moreover, it will test whether the input actually yields a regular matroid, unlike this class. For direct access to the `RegularMatroid` constructor, run:

  Sage

      sage: from sage.matroids.advanced import *

  Python

      >>> from sage.all import *
      >>> from sage.matroids.advanced import *

  Warning

  No checks are performed to ensure the input data form an actual regular matroid! If not, the behavior is unpredictable, and the internal representation can get corrupted. If in doubt, run `self.is_valid()` to ensure the data are as desired.

  EXAMPLES:

  Sage

      sage: A = Matrix(ZZ, 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]])
      sage: M = Matroid(A, regular=True); M                                           # needs sage.graphs
      Regular matroid of rank 2 on 4 elements with 5 bases
      sage: sorted(M.groundset())                                                     # needs sage.graphs
      [0, 1, 2, 3]
      sage: Matrix(M)                                                                 # needs sage.graphs
      [1 0 1 1]
      [0 1 1 1]
      sage: M = Matroid(matrix=A, groundset='abcd', regular=True)                     # needs sage.graphs
      sage: sorted(M.groundset())                                                     # needs sage.graphs
      ['a', 'b', 'c', 'd']

  Python

      >>> from sage.all import *
      >>> A = Matrix(ZZ, Integer(2), Integer(4), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)]])
      >>> M = Matroid(A, regular=True); M                                           # needs sage.graphs
      Regular matroid of rank 2 on 4 elements with 5 bases
      >>> sorted(M.groundset())                                                     # needs sage.graphs
      [0, 1, 2, 3]
      >>> Matrix(M)                                                                 # needs sage.graphs
      [1 0 1 1]
      [0 1 1 1]
      >>> M = Matroid(matrix=A, groundset='abcd', regular=True)                     # needs sage.graphs
      >>> sorted(M.groundset())                                                     # needs sage.graphs
      ['a', 'b', 'c', 'd']

  base_ring()

    Return the base ring of the matrix representing the matroid, in this case \(\ZZ\).

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.R10()
        sage: M.base_ring()
        Integer Ring

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.R10()
        >>> M.base_ring()
        Integer Ring

  bases_count()

    Count the number of bases.

    EXAMPLES:

    Sage

        sage: M = Matroid(graphs.CompleteGraph(5), regular=True)                    # needs sage.graphs
        sage: M.bases_count()                                                       # needs sage.graphs
        125

    Python

        >>> from sage.all import *
        >>> M = Matroid(graphs.CompleteGraph(Integer(5)), regular=True)                    # needs sage.graphs
        >>> M.bases_count()                                                       # needs sage.graphs
        125

    ALGORITHM:

    Since the matroid is regular, we use Kirchhoff’s Matrix-Tree Theorem. See also Wikipedia article Kirchhoff%27s_theorem.

  binary_matroid(randomized_tests=1, verify=True)

    Return a binary matroid representing `self`.

    INPUT:

    - `randomized_tests` – ignored

    - `verify` – ignored

    OUTPUT: a binary matroid

    ALGORITHM:

    `self` is a regular matroid, so just cast `self` to a BinaryMatroid.

    See also

    `M.binary_matroid()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.R10()
        sage: N.binary_matroid()
        Binary matroid of rank 5 on 10 elements, type (1, None)

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.R10()
        >>> N.binary_matroid()
        Binary matroid of rank 5 on 10 elements, type (1, None)

  characteristic()

    Return the characteristic of the base ring of the matrix representing the matroid, in this case \(0\).

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.R10()
        sage: M.characteristic()
        0

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.R10()
        >>> M.characteristic()
        0

  has_line_minor(k, hyperlines=None, certificate=False)

    Test if the matroid has a \(U_{2, k}\)-minor.

    The matroid \(U_{2, k}\) is a matroid on \(k\) elements in which every subset of at most 2 elements is independent, and every subset of more than two elements is dependent.

    The optional argument `hyperlines` restricts the search space: this method returns `True` if \(si(M/F)\) is isomorphic to \(U_{2, l}\) with \(l \geq k\) for some \(F\) in `hyperlines`, and `False` otherwise.

    INPUT:

    - `k` – the length of the line minor

    - `hyperlines` – (default: `None`) a set of flats of codimension 2. Defaults to the set of all flats of codimension 2.

    - `certificate` – (default: `False`) if `True` returns `True, F`, where `F` is a flat and `self.minor(contractions=F)` has a \(U_{2,k}\) restriction or `False, None`

    OUTPUT: boolean or tuple

    See also

    `Matroid.has_minor()`

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.R10()
        sage: M.has_line_minor(4)
        False
        sage: M.has_line_minor(4, certificate=True)
        (False, None)
        sage: M.has_line_minor(3)
        True
        sage: M.has_line_minor(3, certificate=True)
        (True, frozenset({'a', 'b', 'c', 'g'}))
        sage: M.has_line_minor(k=3, hyperlines=[['a', 'b', 'c'],
        ....:                                   ['a', 'b', 'd' ]])
        True
        sage: M.has_line_minor(k=3, hyperlines=[['a', 'b', 'c'],
        ....:                                   ['a', 'b', 'd' ]], certificate=True)
        (True, frozenset({'a', 'b', 'c'}))

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.R10()
        >>> M.has_line_minor(Integer(4))
        False
        >>> M.has_line_minor(Integer(4), certificate=True)
        (False, None)
        >>> M.has_line_minor(Integer(3))
        True
        >>> M.has_line_minor(Integer(3), certificate=True)
        (True, frozenset({'a', 'b', 'c', 'g'}))
        >>> M.has_line_minor(k=Integer(3), hyperlines=[['a', 'b', 'c'],
        ...                                   ['a', 'b', 'd' ]])
        True
        >>> M.has_line_minor(k=Integer(3), hyperlines=[['a', 'b', 'c'],
        ...                                   ['a', 'b', 'd' ]], certificate=True)
        (True, frozenset({'a', 'b', 'c'}))

  is_binary(randomized_tests=1)

    Decide if `self` is a binary matroid.

    INPUT:

    - `randomized_tests` – ignored

    OUTPUT: boolean

    ALGORITHM:

    `self` is a regular matroid, so just return `True`.

    See also

    `M.is_binary()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.R10()
        sage: N.is_binary()
        True

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.R10()
        >>> N.is_binary()
        True

  is_graphic()

    Test if the regular matroid is graphic.

    A matroid is graphic if there exists a graph whose edge set equals the groundset of the matroid, such that a subset of elements of the matroid is independent if and only if the corresponding subgraph is acyclic.

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.R10()
        sage: M.is_graphic()
        False
        sage: M = Matroid(graphs.CompleteGraph(5), regular=True)                    # needs sage.graphs
        sage: M.is_graphic()                                                        # needs sage.graphs sage.rings.finite_rings
        True
        sage: M.dual().is_graphic()                                                 # needs sage.graphs
        False

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.R10()
        >>> M.is_graphic()
        False
        >>> M = Matroid(graphs.CompleteGraph(Integer(5)), regular=True)                    # needs sage.graphs
        >>> M.is_graphic()                                                        # needs sage.graphs sage.rings.finite_rings
        True
        >>> M.dual().is_graphic()                                                 # needs sage.graphs
        False

    ALGORITHM:

    In a recent paper, Geelen and Gerards [GG2012] reduced the problem to testing if a system of linear equations has a solution. While not the fastest method, and not necessarily constructive (in the presence of 2-separations especially), it is easy to implement.

  is_regular()

    Return if `self` is regular.

    This is trivially `True` for a `RegularMatroid`.

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.R10()
        sage: M.is_regular()
        True

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.R10()
        >>> M.is_regular()
        True

  is_ternary(randomized_tests=1)

    Decide if `self` is a ternary matroid.

    INPUT:

    - `randomized_tests` – ignored

    OUTPUT: boolean

    ALGORITHM:

    `self` is a regular matroid, so just return `True`.

    See also

    `M.is_ternary()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.R10()
        sage: N.is_ternary()
        True

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.R10()
        >>> N.is_ternary()
        True

  is_valid(certificate=False)

    Test if the data obey the matroid axioms.

    Since this is a regular matroid, this function tests if the representation matrix is totally unimodular, i.e. if all square submatrices have determinant in \(\{-1, 0, 1\}\).

    INPUT:

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

    OUTPUT: boolean, or (boolean, dictionary)

    EXAMPLES:

    Sage

        sage: # needs sage.graphs
        sage: M = Matroid(Matrix(ZZ, [[1, 0, 0, 1, 1, 0, 1],
        ....:                         [0, 1, 0, 1, 0, 1, 1],
        ....:                         [0, 0, 1, 0, 1, 1, 1]]),
        ....:             regular=True, check=False)
        sage: M.is_valid(certificate=True)
        (False, {'error': 'the representation matrix is not totally unimodular'})
        sage: M = Matroid(graphs.PetersenGraph())
        sage: M.is_valid()
        True

    Python

        >>> from sage.all import *
        >>> # needs sage.graphs
        >>> M = Matroid(Matrix(ZZ, [[Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1)],
        ...                         [Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(1)],
        ...                         [Integer(0), Integer(0), Integer(1), Integer(0), Integer(1), Integer(1), Integer(1)]]),
        ...             regular=True, check=False)
        >>> M.is_valid(certificate=True)
        (False, {'error': 'the representation matrix is not totally unimodular'})
        >>> M = Matroid(graphs.PetersenGraph())
        >>> M.is_valid()
        True

  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: M = matroids.catalog.R10()
        sage: sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
        sage: N = M.relabel({'g': 'x'})
        sage: sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'x']

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.R10()
        >>> sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
        >>> N = M.relabel({'g': 'x'})
        >>> sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'x']

  ternary_matroid(randomized_tests=1, verify=True)

    Return a ternary matroid representing `self`.

    INPUT:

    - `randomized_tests` – ignored

    - `verify` – ignored

    OUTPUT: a ternary matroid

    ALGORITHM:

    `self` is a regular matroid, so just cast `self` to a TernaryMatroid.

    See also

    `M.ternary_matroid()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.R10()
        sage: N.ternary_matroid()
        Ternary matroid of rank 5 on 10 elements, type 4+

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.R10()
        >>> N.ternary_matroid()
        Ternary matroid of rank 5 on 10 elements, type 4+

class sage.matroids.linear_matroid.TernaryMatroid

  Bases: `LinearMatroid`

  Ternary matroids.

  A ternary matroid is a linear matroid represented over the finite field with three elements. See `LinearMatroid` for a definition.

  The simplest way to create a `TernaryMatroid` is by giving only a matrix \(A\). Then, the groundset defaults to `range(A.ncols())`. Any iterable object \(E\) can be given as a groundset. If \(E\) is a list, then `E[i]` will label the \(i\)-th column of \(A\). Another possibility is to specify a ‘reduced’ matrix \(B\), to create the matroid induced by \(A = [I\ \ B]\).

  INPUT:

  - `matrix` – (default: `None`) a matrix whose column vectors represent the matroid.

  - `reduced_matrix` – (default: `None`) a matrix \(B\) such that \([I\ \ B]\) represents the matroid, where \(I\) is an identity matrix with the same number of rows as \(B\). Only one of `matrix` and `reduced_matrix` should be provided.

  - `groundset` – (default: `None`) an iterable containing the element labels. When provided, must have the correct number of elements: the number of columns of `matrix` or the number of rows plus the number of columns of `reduced_matrix`.

  - `ring` – (default: `None`) ignored

  - `keep_initial_representation` – boolean (default: `True`); decides whether or not an internal copy of the input matrix should be preserved. This can help to see the structure of the matroid (e.g. in the case of graphic matroids), and makes it easier to look at extensions. However, the input matrix may have redundant rows, and sometimes it is desirable to store only a row-reduced copy.

  - `basis` – (default: `None`) when provided, this is an ordered subset of `groundset`, such that the submatrix of `matrix` indexed by `basis` is an identity matrix. In this case, no row reduction takes place in the initialization phase.

  OUTPUT: a `TernaryMatroid` instance based on the data above

  Note

  The recommended way to generate a ternary matroid is through the `Matroid()` function. This is usually the preferred way, since it automatically chooses between `TernaryMatroid` and other classes. For direct access to the `TernaryMatroid` constructor, run:

  Sage

      sage: from sage.matroids.advanced import *

  Python

      >>> from sage.all import *
      >>> from sage.matroids.advanced import *

  EXAMPLES:

  Sage

      sage: A = Matrix(GF(3), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]])
      sage: M = Matroid(A); M
      Ternary matroid of rank 2 on 4 elements, type 0-
      sage: sorted(M.groundset())
      [0, 1, 2, 3]
      sage: Matrix(M)
      [1 0 1 1]
      [0 1 1 1]
      sage: M = Matroid(matrix=A, groundset='abcd')
      sage: sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      sage: B = Matrix(GF(2), 2, 2, [[1, 1], [1, 1]])
      sage: N = Matroid(ring=GF(3), reduced_matrix=B, groundset='abcd')               # needs sage.rings.finite_rings
      sage: M == N                                                                    # needs sage.rings.finite_rings
      True

  Python

      >>> from sage.all import *
      >>> A = Matrix(GF(Integer(3)), Integer(2), Integer(4), [[Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)]])
      >>> M = Matroid(A); M
      Ternary matroid of rank 2 on 4 elements, type 0-
      >>> sorted(M.groundset())
      [0, 1, 2, 3]
      >>> Matrix(M)
      [1 0 1 1]
      [0 1 1 1]
      >>> M = Matroid(matrix=A, groundset='abcd')
      >>> sorted(M.groundset())
      ['a', 'b', 'c', 'd']
      >>> B = Matrix(GF(Integer(2)), Integer(2), Integer(2), [[Integer(1), Integer(1)], [Integer(1), Integer(1)]])
      >>> N = Matroid(ring=GF(Integer(3)), reduced_matrix=B, groundset='abcd')               # needs sage.rings.finite_rings
      >>> M == N                                                                    # needs sage.rings.finite_rings
      True

  base_ring()

    Return the base ring of the matrix representing the matroid, in this case \(\GF{3}\).

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.NonFano()
        sage: M.base_ring()
        Finite Field of size 3

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.NonFano()
        >>> M.base_ring()
        Finite Field of size 3

  bicycle_dimension()

    Return the bicycle dimension of the ternary matroid.

    The bicycle dimension of a linear subspace \(V\) is \(\dim(V\cap V^\perp)\). The bicycle dimension of a matroid equals the bicycle dimension of its rowspace, and is a matroid invariant. See [Pen2012].

    OUTPUT: integer

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.NonFano()
        sage: M.bicycle_dimension()
        0

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.NonFano()
        >>> M.bicycle_dimension()
        0

  character()

    Return the character of the ternary matroid.

    For a linear subspace \(V\) over \(GF(3)\) with orthogonal basis \(q_1, \ldots, q_k\) the character equals the product of \(|q_i|\) modulo 3, where the product ranges over the \(i\) such that \(|q_i|\) is not divisible by 3. The character does not depend on the choice of the orthogonal basis. The character of a ternary matroid equals the character of its cocycle-space, and is an invariant for ternary matroids. See [Pen2012].

    OUTPUT: integer

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.NonFano()
        sage: M.character()
        2

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.NonFano()
        >>> M.character()
        2

  characteristic()

    Return the characteristic of the base ring of the matrix representing the matroid, in this case \(3\).

    EXAMPLES:

    Sage

        sage: M = matroids.catalog.NonFano()
        sage: M.characteristic()
        3

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.NonFano()
        >>> M.characteristic()
        3

  is_ternary(randomized_tests=1)

    Decide if `self` is a binary matroid.

    INPUT:

    - `randomized_tests` – ignored

    OUTPUT: boolean

    ALGORITHM:

    `self` is a ternary matroid, so just return `True`.

    See also

    `M.is_ternary()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.NonFano()
        sage: N.is_ternary()
        True

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.NonFano()
        >>> N.is_ternary()
        True

  is_valid(certificate=False)

    Test if the data obey the matroid axioms.

    Since this is a linear matroid over the field \(\GF{3}\), this is always the case.

    INPUT:

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

    OUTPUT: `True`, or `(True, {})`

    EXAMPLES:

    Sage

        sage: M = Matroid(Matrix(GF(3), [[]]))
        sage: M.is_valid()
        True

    Python

        >>> from sage.all import *
        >>> M = Matroid(Matrix(GF(Integer(3)), [[]]))
        >>> M.is_valid()
        True

  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: M = matroids.catalog.NonFano()
        sage: sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        sage: N = M.relabel({'g': 'x'})
        sage: sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

    Python

        >>> from sage.all import *
        >>> M = matroids.catalog.NonFano()
        >>> sorted(M.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']
        >>> N = M.relabel({'g': 'x'})
        >>> sorted(N.groundset())
        ['a', 'b', 'c', 'd', 'e', 'f', 'x']

  ternary_matroid(randomized_tests=1, verify=True)

    Return a ternary matroid representing `self`.

    INPUT:

    - `randomized_tests` – ignored

    - `verify` – ignored

    OUTPUT: a binary matroid

    ALGORITHM:

    `self` is a ternary matroid, so just return `self`.

    See also

    `M.ternary_matroid()`

    EXAMPLES:

    Sage

        sage: N = matroids.catalog.NonFano()
        sage: N.ternary_matroid() is N
        True

    Python

        >>> from sage.all import *
        >>> N = matroids.catalog.NonFano()
        >>> N.ternary_matroid() is N
        True