I’m back with more on matroid computation in Sage. Previous installments are here, here, and here. As in the previous post, clicking the “Evaluate” buttons below will execute the code and return the answer. The various computations are again linked, so execute them in the right order.

Today we will look at various ways to ask (and answer) the question “*Are these two matroids equal?*” There are some subtle aspects to this, since we had to balance efficiency of the code and mathematical interpretation. The result is that we have various ways to compare matroids.

# Isomorphism

Matroids $M$ and $N$ are *isomorphic* if there is a bijection $\phi: E(M) \to E(N)$ mapping bases to bases and nonbases to nonbases. In Sage, we check this as follows:

In other words, every matroid in Sage has a method `.is_isomorphic()`

taking another matroid as input and returning True or False. Currently there is no way to extract the actual isomorphism (it is on our wish list), but if you guessed one, you can check its correctness:

We defined $\phi$ using a *dictionary*: for instance, `phi['c']`

equals `2`

. If you defined your map differently (e.g. as a function or a permutation), Sage will probably understand that too.

# Equality

Matroids $M$ and $N$ are *equal* if $E(M) = E(N)$ and the identity map is an isomorphism. We can check for equality as follows:

# ==

The standard way to compare two objects in Sage is through the comparison operator `==`

. For instance,

When writing the matroid code, we chose to interpret the question `M == N`

to mean “*Is the internal representation of the matroid $M$ equal to the internal representation of $N$?*” This is a very restricted view: the only time

`M == N`

will return `True`

is if- $M$ and $N$ have the same internal data structure (i.e. both are of type
`BasisMatroid`

or both are of type`LinearMatroid`

or …) - $M$ and $N$ are equal as matroids
- The internal representations are equivalent (this is at the moment only relevant for linear matroids).

Let’s consider a few examples:

So only matroids $M_1$, $M_2$, and $M_4$ pass the equality test. This is because they are all linear matroids over the field $\mathrm{GF}(2)$, have the same ground set, and the matrices are *projectively equivalent*: one can be turned into the other using only row operations and column scaling. Matrix $M_3$ is isomorphic to $M_1$ but not equal; matroid $M_5$ is represented over a different field; matroid $M_6$ is represented by a list of bases, and matroid $M_7$ is represented by a list of “circuit closures”.

This notion of equality has consequences for programming. In Python, a `set`

is a data structure containing at most one copy of each element.

So $S$ actually contains $M_3, M_5, M_6, M_7$, and one copy of $M_1, M_2, M_4$.

This means, unfortunately, that you cannot rely on Python’s default filtering tools for sets if you want only matroidally equal objects, or only isomorphic objects. But those equality tests are way more expensive computationally, whereas in many applications the matroids in a set will be of the same type anyway.

# Inequivalent representations

As mentioned above, each instance of the `LinearMatroid`

class is considered a *represented* matroid. There are specialized methods for testing projective equivalence and projective isomorphism. Recall that matroids are projectively equivalent (in Sage’s terminology, field-equivalent) if the representation matrices are equal up to row operations and column scaling. So below, matroids $M_1$ and $M_3$ are field-equivalent; matroids $M_1$ and $M_4$ are field-isomorphic; and matroid $M_2$ has an inequivalent representation:

I probably caused a lot of confusion, so feel free to ask questions in the comments below. Also, the documentation for the functions discussed above gives more explanations and examples.