Seymour’s decomposition of totally unimodular matrices and regular matroids

This module is provided by the pip-installable package passagemath-cmr.

class sage.matrix.seymour_decomposition.BaseGraphicNode[source]

Bases: DecompositionNode

Base class for GraphicNode, CographicNode, and PlanarNode

If base_ring is \(\GF{2}\), then it represents a graphic/cographic/planar matroid.

Suppose that self.matrix() is a graphic matrix of a graph \(G\) with respect to \(T\), a spanning forest of the graph \(G\).

  • self._graph is the graph \(G = (V,E)\).

  • self._forest_edges is the edges of \(T\).

  • self._coforest_edges is the edges of \(E \setminus T\).

If base_ring is \(\GF{3}\) or \(\ZZ\), then it represents a network/conetwork or a both network and conetwork matrix.

Suppose that self.matrix() is a network matrix of a digraph \(D\) with respect to \(T\), a directed spanning forest of the underlying undirected graph.

  • self._graph is the digraph \(D = (V,A)\).

  • self._forest_edges is the arcs of \(T\).

  • self._coforest_edges is the arcs of \(A \setminus T\).

coforest_edges()[source]

Return the forest edges of self.

If self.base_ring() is \(\GF{2}\), then return edges. If self.base_ring() is \(\GF{3}\) or \(\ZZ\), then arcs.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 7, sparse=True),
....:                           [[-1,  0,  0,  0,  1, -1,  0],
....:                            [ 1,  0,  0,  1, -1,  1,  0],
....:                            [ 0, -1,  0, -1,  1, -1,  0],
....:                            [ 0,  1,  0,  0,  0,  0,  1],
....:                            [ 0,  0,  1, -1,  1,  0,  1],
....:                            [ 0,  0, -1,  1, -1,  0,  0]])
sage: M.is_network_matrix()
True
sage: result, certificate = M.is_network_matrix(certificate=True)
sage: result, certificate
(True,
 (Digraph on 7 vertices,
  ((9, 8), (3, 8), (3, 4), (5, 4), (4, 6), (0, 6)),
  ((3, 9), (5, 3), (4, 0), (0, 8), (9, 0), (4, 9), (5, 6))))
sage: digraph, forest_arcs, coforest_arcs = certificate
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: certificate.graph() == digraph
True
sage: certificate.forest_edges() == forest_arcs
True
sage: certificate.coforest_edges() == coforest_arcs
True
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(7), sparse=True),
...                           [[-Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0)],
...                            [ Integer(1),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(1),  Integer(0)],
...                            [ Integer(0), -Integer(1),  Integer(0), -Integer(1),  Integer(1), -Integer(1),  Integer(0)],
...                            [ Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1)],
...                            [ Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(1),  Integer(0),  Integer(1)],
...                            [ Integer(0),  Integer(0), -Integer(1),  Integer(1), -Integer(1),  Integer(0),  Integer(0)]])
>>> M.is_network_matrix()
True
>>> result, certificate = M.is_network_matrix(certificate=True)
>>> result, certificate
(True,
 (Digraph on 7 vertices,
  ((9, 8), (3, 8), (3, 4), (5, 4), (4, 6), (0, 6)),
  ((3, 9), (5, 3), (4, 0), (0, 8), (9, 0), (4, 9), (5, 6))))
>>> digraph, forest_arcs, coforest_arcs = certificate
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> certificate.graph() == digraph
True
>>> certificate.forest_edges() == forest_arcs
True
>>> certificate.coforest_edges() == coforest_arcs
True
forest_edges()[source]

Return the forest edges of self.

If self.base_ring() is \(\GF{2}\), then return edges. If self.base_ring() is \(\GF{3}\) or \(\ZZ\), then arcs.

EXAMPLES:

Undirected graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [1, 1], [0,1]]); M
[1 0]
[1 1]
[0 1]
sage: result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.forest_edges()
((1, 2), (7, 1), (12, 7))
sage: certificate.coforest_edges()
((2, 7), (1, 12))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [Integer(1), Integer(1)], [Integer(0),Integer(1)]]); M
[1 0]
[1 1]
[0 1]
>>> result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.forest_edges()
((1, 2), (7, 1), (12, 7))
>>> certificate.coforest_edges()
((2, 7), (1, 12))

Directed graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0,-1]]); M
[ 1  0]
[-1  1]
[ 0 -1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.forest_edges()
((2, 1), (7, 1), (7, 12))
sage: certificate.coforest_edges()
((2, 7), (12, 1))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0),-Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0 -1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.forest_edges()
((2, 1), (7, 1), (7, 12))
>>> certificate.coforest_edges()
((2, 7), (12, 1))

Starting with a morphism:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: phi = matrix(ZZ, [[1, 0], [1, 1], [0, 1]],
....:              row_keys=['a', 'b', 'c'], column_keys=['v', 'w'])
sage: phi; phi._unicode_art_matrix()
Generic morphism:
From: Free module generated by {'v', 'w'} over Integer Ring
To:   Free module generated by {'a', 'b', 'c'} over Integer Ring
  v w
a⎛1 0⎞
b⎜1 1⎟
c⎝0 1⎠
sage: phi_node = UnknownNode(phi)
sage: is_graphic, rephined_node = phi_node._is_binary_linear_matroid_graphic(decomposition=True)
sage: is_graphic, rephined_node
(True, GraphicNode (3×2))
sage: rephined_node.forest_edges()
{'a': (1, 2), 'b': (7, 1), 'c': (12, 7)}
sage: phi_node  # still in the dark about graphicness
UnknownNode (3×2)
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> phi = matrix(ZZ, [[Integer(1), Integer(0)], [Integer(1), Integer(1)], [Integer(0), Integer(1)]],
...              row_keys=['a', 'b', 'c'], column_keys=['v', 'w'])
>>> phi; phi._unicode_art_matrix()
Generic morphism:
From: Free module generated by {'v', 'w'} over Integer Ring
To:   Free module generated by {'a', 'b', 'c'} over Integer Ring
  v w
a⎛1 0⎞
b⎜1 1⎟
c⎝0 1⎠
>>> phi_node = UnknownNode(phi)
>>> is_graphic, rephined_node = phi_node._is_binary_linear_matroid_graphic(decomposition=True)
>>> is_graphic, rephined_node
(True, GraphicNode (3×2))
>>> rephined_node.forest_edges()
{'a': (1, 2), 'b': (7, 1), 'c': (12, 7)}
>>> phi_node  # still in the dark about graphicness
UnknownNode (3×2)
graph()[source]

Return the graph representing self.

If self.base_ring() is \(\GF{2}\), then return an undirected graph. If self.base_ring() is \(\GF{3}\) or \(\ZZ\), then return directed graph.

EXAMPLES:

Undirected graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [1, 1], [0,1]]); M
[1 0]
[1 1]
[0 1]
sage: result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: G = certificate.graph(); G
Graph on 4 vertices
sage: G.vertices(sort=True)
[1, 2, 7, 12]
sage: G.edges(sort=True)
[(1, 2, None), (1, 7, None), (1, 12, None), (2, 7, None), (7, 12, None)]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [Integer(1), Integer(1)], [Integer(0),Integer(1)]]); M
[1 0]
[1 1]
[0 1]
>>> result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> G = certificate.graph(); G
Graph on 4 vertices
>>> G.vertices(sort=True)
[1, 2, 7, 12]
>>> G.edges(sort=True)
[(1, 2, None), (1, 7, None), (1, 12, None), (2, 7, None), (7, 12, None)]

Directed graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0,-1]]); M
[ 1  0]
[-1  1]
[ 0 -1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: G = certificate.graph(); G
Digraph on 4 vertices
sage: G.vertices(sort=True)
[1, 2, 7, 12]
sage: G.edges(sort=True)
[(2, 1, None), (2, 7, None), (7, 1, None), (7, 12, None), (12, 1, None)]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0),-Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0 -1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> G = certificate.graph(); G
Digraph on 4 vertices
>>> G.vertices(sort=True)
[1, 2, 7, 12]
>>> G.edges(sort=True)
[(2, 1, None), (2, 7, None), (7, 1, None), (7, 12, None), (12, 1, None)]
class sage.matrix.seymour_decomposition.CographicNode[source]

Bases: BaseGraphicNode

coforest_edges()[source]

Return the forest edges of the cograph of self.

forest_edges()[source]

Return the forest edges of the cograph of self.

EXAMPLES:

Undirected graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 4, 5, sparse=True),
....:                           [[1, 1, 1, 0, 0],
....:                            [0, 1, 1, 1, 0],
....:                            [0, 0, 1, 1, 1],
....:                            [1, 0, 0, 1, 1]]); M
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
sage: result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
sage: result, certificate
(True, CographicNode (4×5))
sage: certificate.forest_edges()
((7, 8), (5, 0), (0, 7), (1, 7), (2, 1))
sage: certificate.coforest_edges()
((5, 8), (5, 1), (0, 2), (2, 8))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(4), Integer(5), sparse=True),
...                           [[Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1), Integer(1), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(1)]]); M
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
>>> result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
>>> result, certificate
(True, CographicNode (4×5))
>>> certificate.forest_edges()
((7, 8), (5, 0), (0, 7), (1, 7), (2, 1))
>>> certificate.coforest_edges()
((5, 8), (5, 1), (0, 2), (2, 8))

Directed graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 4, 5, sparse=True),
....:                           [[1, -1, 1, 0, 0],
....:                            [0, 1, -1, 1, 0],
....:                            [0, 0, 1, -1, 1],
....:                            [1, 0, 0, 1, -1]]); M
[ 1 -1  1  0  0]
[ 0  1 -1  1  0]
[ 0  0  1 -1  1]
[ 1  0  0  1 -1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, CographicNode (4×5))
sage: certificate.forest_edges()
((7, 8), (0, 5), (0, 7), (1, 7), (1, 2))
sage: certificate.coforest_edges()
((5, 8), (1, 5), (0, 2), (2, 8))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(4), Integer(5), sparse=True),
...                           [[Integer(1), -Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1), -Integer(1), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), -Integer(1), Integer(1)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), -Integer(1)]]); M
[ 1 -1  1  0  0]
[ 0  1 -1  1  0]
[ 0  0  1 -1  1]
[ 1  0  0  1 -1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, CographicNode (4×5))
>>> certificate.forest_edges()
((7, 8), (0, 5), (0, 7), (1, 7), (1, 2))
>>> certificate.coforest_edges()
((5, 8), (1, 5), (0, 2), (2, 8))
graph()[source]

Actually the cograph of matrix, in the case where it is not graphic.

EXAMPLES:

Undirected graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 4, 5, sparse=True),
....:                           [[1, 1, 1, 0, 0],
....:                            [0, 1, 1, 1, 0],
....:                            [0, 0, 1, 1, 1],
....:                            [1, 0, 0, 1, 1]]); M
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
sage: result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
sage: certificate
CographicNode (4×5)
sage: certificate.base_ring()
Finite Field of size 2
sage: G = certificate.graph(); G
Graph on 6 vertices
sage: G.vertices(sort=True)
[0, 1, 2, 5, 7, 8]
sage: G.edges(sort=True)
[(0, 2, None), (0, 5, None), (0, 7, None), (1, 2, None), (1, 5, None),
 (1, 7, None), (2, 8, None), (5, 8, None), (7, 8, None)]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(4), Integer(5), sparse=True),
...                           [[Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1), Integer(1), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(1)]]); M
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
>>> result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
>>> certificate
CographicNode (4×5)
>>> certificate.base_ring()
Finite Field of size 2
>>> G = certificate.graph(); G
Graph on 6 vertices
>>> G.vertices(sort=True)
[0, 1, 2, 5, 7, 8]
>>> G.edges(sort=True)
[(0, 2, None), (0, 5, None), (0, 7, None), (1, 2, None), (1, 5, None),
 (1, 7, None), (2, 8, None), (5, 8, None), (7, 8, None)]

Directed graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 4, 5, sparse=True),
....:                           [[1, -1, 1, 0, 0],
....:                            [0, 1, -1, 1, 0],
....:                            [0, 0, 1, -1, 1],
....:                            [1, 0, 0, 1, -1]]); M
[ 1 -1  1  0  0]
[ 0  1 -1  1  0]
[ 0  0  1 -1  1]
[ 1  0  0  1 -1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: certificate
CographicNode (4×5)
sage: G = certificate.graph(); G
Digraph on 6 vertices
sage: G.vertices(sort=True)
[0, 1, 2, 5, 7, 8]
sage: G.edges(sort=True)
[(0, 2, None), (0, 5, None), (0, 7, None), (1, 2, None), (1, 5, None),
 (1, 7, None), (2, 8, None), (5, 8, None), (7, 8, None)]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(4), Integer(5), sparse=True),
...                           [[Integer(1), -Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1), -Integer(1), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), -Integer(1), Integer(1)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), -Integer(1)]]); M
[ 1 -1  1  0  0]
[ 0  1 -1  1  0]
[ 0  0  1 -1  1]
[ 1  0  0  1 -1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> certificate
CographicNode (4×5)
>>> G = certificate.graph(); G
Digraph on 6 vertices
>>> G.vertices(sort=True)
[0, 1, 2, 5, 7, 8]
>>> G.edges(sort=True)
[(0, 2, None), (0, 5, None), (0, 7, None), (1, 2, None), (1, 5, None),
 (1, 7, None), (2, 8, None), (5, 8, None), (7, 8, None)]
class sage.matrix.seymour_decomposition.DecompositionNode[source]

Bases: SageObject

Base class for nodes in Seymour’s decomposition

as_ordered_tree()[source]

Return the decomposition tree rooted at self.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = matrix([[1, 0], [-1, 1], [0, 1]], sparse=True)
sage: M2 = block_diagonal_matrix([M, M], sparse=True)
sage: M2cmr = Matrix_cmr_chr_sparse(M2.parent(), M2); M2cmr
[ 1  0  0  0]
[-1  1  0  0]
[ 0  1  0  0]
[ 0  0  1  0]
[ 0  0 -1  1]
[ 0  0  0  1]
sage: result, certificate = M2cmr.is_totally_unimodular(certificate=True)
sage: T = certificate.as_ordered_tree(); T
OneSumNode (6×4) with 2 children[GraphicNode (3×2)[], GraphicNode (3×2)[]]
sage: unicode_art(T)
╭───────────OneSumNode (6×4) with 2 children
│                 │
GraphicNode (3×2) GraphicNode (3×2)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = matrix([[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]], sparse=True)
>>> M2 = block_diagonal_matrix([M, M], sparse=True)
>>> M2cmr = Matrix_cmr_chr_sparse(M2.parent(), M2); M2cmr
[ 1  0  0  0]
[-1  1  0  0]
[ 0  1  0  0]
[ 0  0  1  0]
[ 0  0 -1  1]
[ 0  0  0  1]
>>> result, certificate = M2cmr.is_totally_unimodular(certificate=True)
>>> T = certificate.as_ordered_tree(); T
OneSumNode (6×4) with 2 children[GraphicNode (3×2)[], GraphicNode (3×2)[]]
>>> unicode_art(T)
╭───────────OneSumNode (6×4) with 2 children
│                 │
GraphicNode (3×2) GraphicNode (3×2)
base_ring()[source]

Return the base ring of the matrix representing the node.

child_keys()[source]

Return a tuple of the tuples of the row and column keys of children in the parent node.

OUTPUT: a tuple of (row keys, column keys)

If the number of children is 1, then output (row keys, column keys).

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: certificate.child_keys()
()

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = matrix([[1, 0], [-1, 1], [0, 1]], sparse=True)
sage: M2 = block_diagonal_matrix([M, M], sparse=True)
sage: M2cmr = Matrix_cmr_chr_sparse(M2.parent(), M2); M2cmr
[ 1  0  0  0]
[-1  1  0  0]
[ 0  1  0  0]
[ 0  0  1  0]
[ 0  0 -1  1]
[ 0  0  0  1]
sage: result, certificate = M2cmr.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, OneSumNode (6×4) with 2 children)
sage: C = certificate.summands(); C
(GraphicNode (3×2), GraphicNode (3×2))
sage: certificate.child_keys()[0]
((0, 1, 2), (0, 1))
sage: certificate.child_keys()[1]
((3, 4, 5), (2, 3))

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 12, sparse=True),
....:           [[ 1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1],
....:            [ 0,  0,  0,  1, -1,  0,  0,  0,  1,  1,  1,  1],
....:            [ 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1],
....:            [ 1,  0,  1,  0,  0,  0,  0,  0,  1,  1,  0,  0],
....:            [ 0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1, -1],
....:            [ 0,  0,  0,  1,  0,  1,  0,  0,  1,  1,  0,  0],
....:            [ 0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1, -1],
....:            [ 0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0],
....:            [ 0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1]])
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="delta_pivot",
....:                           row_keys=['r1', 'r2', 'r3', 'r4', 'r5',
....:                                     'r6', 'r7', 'r8', 'r9'],
....:                           column_keys=['a','b','c','d','e','f',
....:                                        'g','h','i','j','k','l'])
sage: C = certificate.child_nodes()[0]; C
DeltaSumNode (9×12)
sage: C1, C2 = C.child_nodes()
sage: C1.matrix()
[ 0  0  1  1  1  1  1]
[ 1  1  0  0  0 -1 -1]
[ 1  0 -1  0 -1 -1 -1]
[ 0  1  1  0  1  0  0]
[ 0  0  0 -1 -1  0 -1]
sage: C2.matrix()
[-1  0  1 -1  0  0  0  0 -1]
[ 0  0 -1  1  0  1 -1  0  1]
[ 1  1  0  1  1  0  0  0  1]
[ 1  1  0  1  1  0  0  0  0]
[ 1  1 -1  1  0  1  0  1  1]
[ 1  1  0  0  0  0  1  1  0]
sage: certificate.child_keys()
((i, r2, r3, r4, r5, r6, r7, r8, r9), (a, b, c, d, e, f, g, h, r1, j, k, l))
sage: C.matrix()
[ 1 -1  0  0  0  0  0  0 -1  1  1  1]
[-1  1  0  1 -1  0  0  0  1  0  0  0]
[-1  1  0  0  0  0  1  1  1  0  0  0]
[ 0  1  1  0  0  0  0  0  1  0 -1 -1]
[ 0  1  1  0  0  0  0  0  0  0 -1 -1]
[-1  1  0  1  0  1  0  0  1  0 -1 -1]
[ 0  0  0  0  1  1  0  0  0  0 -1 -1]
[-1  1  0  0  0  0  1  0  1 -1  0 -1]
[ 0  0  0  0  0  0  0  1  0  1  0  1]
sage: C.child_keys()
(((i, r3, r8, r9, r4), (g, h, j, k, l, a, +a-r4)),
 ((i, r2, r4, r5, r6, r7), (-i+k, k, a, b, c, d, e, f, r1)))

sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 2, 2, sparse=True),
....:                            [[1, 1], [-1, 0]]); M2
[ 1  1]
[-1  0]
sage: result, certificate = M2.is_totally_unimodular(certificate=True); certificate
GraphicNode (2×2)
sage: certificate.child_keys()
()
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> certificate.child_keys()
()

>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = matrix([[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]], sparse=True)
>>> M2 = block_diagonal_matrix([M, M], sparse=True)
>>> M2cmr = Matrix_cmr_chr_sparse(M2.parent(), M2); M2cmr
[ 1  0  0  0]
[-1  1  0  0]
[ 0  1  0  0]
[ 0  0  1  0]
[ 0  0 -1  1]
[ 0  0  0  1]
>>> result, certificate = M2cmr.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, OneSumNode (6×4) with 2 children)
>>> C = certificate.summands(); C
(GraphicNode (3×2), GraphicNode (3×2))
>>> certificate.child_keys()[Integer(0)]
((0, 1, 2), (0, 1))
>>> certificate.child_keys()[Integer(1)]
((3, 4, 5), (2, 3))

>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(12), sparse=True),
...           [[ Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...            [ Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1)]])
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="delta_pivot",
...                           row_keys=['r1', 'r2', 'r3', 'r4', 'r5',
...                                     'r6', 'r7', 'r8', 'r9'],
...                           column_keys=['a','b','c','d','e','f',
...                                        'g','h','i','j','k','l'])
>>> C = certificate.child_nodes()[Integer(0)]; C
DeltaSumNode (9×12)
>>> C1, C2 = C.child_nodes()
>>> C1.matrix()
[ 0  0  1  1  1  1  1]
[ 1  1  0  0  0 -1 -1]
[ 1  0 -1  0 -1 -1 -1]
[ 0  1  1  0  1  0  0]
[ 0  0  0 -1 -1  0 -1]
>>> C2.matrix()
[-1  0  1 -1  0  0  0  0 -1]
[ 0  0 -1  1  0  1 -1  0  1]
[ 1  1  0  1  1  0  0  0  1]
[ 1  1  0  1  1  0  0  0  0]
[ 1  1 -1  1  0  1  0  1  1]
[ 1  1  0  0  0  0  1  1  0]
>>> certificate.child_keys()
((i, r2, r3, r4, r5, r6, r7, r8, r9), (a, b, c, d, e, f, g, h, r1, j, k, l))
>>> C.matrix()
[ 1 -1  0  0  0  0  0  0 -1  1  1  1]
[-1  1  0  1 -1  0  0  0  1  0  0  0]
[-1  1  0  0  0  0  1  1  1  0  0  0]
[ 0  1  1  0  0  0  0  0  1  0 -1 -1]
[ 0  1  1  0  0  0  0  0  0  0 -1 -1]
[-1  1  0  1  0  1  0  0  1  0 -1 -1]
[ 0  0  0  0  1  1  0  0  0  0 -1 -1]
[-1  1  0  0  0  0  1  0  1 -1  0 -1]
[ 0  0  0  0  0  0  0  1  0  1  0  1]
>>> C.child_keys()
(((i, r3, r8, r9, r4), (g, h, j, k, l, a, +a-r4)),
 ((i, r2, r4, r5, r6, r7), (-i+k, k, a, b, c, d, e, f, r1)))

>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(2), Integer(2), sparse=True),
...                            [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]]); M2
[ 1  1]
[-1  0]
>>> result, certificate = M2.is_totally_unimodular(certificate=True); certificate
GraphicNode (2×2)
>>> certificate.child_keys()
()
child_nodes()[source]

Return a tuple of the children.

The children are sorted by the ordering inherited from cmr, which is their appearance in the parent.

In the case of SumNode, this is the same as summands().

For graphic or leaf nodes, it returns the empty tuple.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                   [[1, 1], [-1, 0]],
....:                                   [[1, 0], [0,1]]); M
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True); certificate
OneSumNode (6×6) with 4 children
sage: certificate.child_nodes()
(GraphicNode (2×2), GraphicNode (2×2), GraphicNode (1×1), GraphicNode (1×1))

sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 2, 2, sparse=True),
....:                            [[1, 1], [-1, 0]]); M2
[ 1  1]
[-1  0]
sage: result, certificate = M2.is_totally_unimodular(certificate=True); certificate
GraphicNode (2×2)
sage: certificate.child_nodes()
()
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                   [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]],
...                                   [[Integer(1), Integer(0)], [Integer(0),Integer(1)]]); M
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True); certificate
OneSumNode (6×6) with 4 children
>>> certificate.child_nodes()
(GraphicNode (2×2), GraphicNode (2×2), GraphicNode (1×1), GraphicNode (1×1))

>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(2), Integer(2), sparse=True),
...                            [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]]); M2
[ 1  1]
[-1  0]
>>> result, certificate = M2.is_totally_unimodular(certificate=True); certificate
GraphicNode (2×2)
>>> certificate.child_nodes()
()
column_keys()[source]

Return the column keys of this node.

OUTPUT: a tuple or None

EXAMPLES:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode(matrix(ZZ, [[1, 0, 1], [0, 1, 1]]),
....:                    row_keys='ab',
....:                    column_keys=range(3)); node
UnknownNode (2×3)
sage: node.column_keys()
(0, 1, 2)
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode(matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]),
...                    row_keys='ab',
...                    column_keys=range(Integer(3))); node
UnknownNode (2×3)
>>> node.column_keys()
(0, 1, 2)
complete_decomposition(time_limit=60.0, use_direct_graphicness_test=True, prefer_graphicness=True, series_parallel_ok=True, check_graphic_minors_planar=False, stop_when_nonTU=False, stop_when_nonnetwork=False, stop_when_nonconetwork=False, stop_when_nonnetwork_and_nonconetwork=False, decompose_strategy='delta_three', construct_leaf_graphs=False, construct_all_graphs=False)[source]

Complete the Seymour’s decomposition of self over \(\GF{3}\) or \(\ZZ\).

INPUT:

  • stop_when_nonTU – boolean; whether to stop decomposing once being non-TU is determined.

  • stop_when_nonnetwork – boolean; whether to stop decomposing once being non-network is determined.

  • stop_when_nonconetwork – boolean; whether to stop decomposing once being non-conetwork is determined.

  • stop_when_nonnetwork_and_nonconetwork – boolean; whether to stop decomposing once not being network and not being conetwork is determined.

For a description of other parameters, see sage.matrix.matrix_cmr_sparse._set_cmr_seymour_parameters().

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 9, sparse=True),
....:                           [[1, 1, 0, 0, 0, 0, 0, 0, 0],
....:                            [1, 1, 1, 0, 0, 0, 0, 0, 0],
....:                            [1, 0, 0, 1, 0, 0, 0, 0, 0],
....:                            [0, 1, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 0, 0, 1, 1, 1, 0, 0],
....:                            [0, 0, 0, 0, 1, 1, 0, 1, 0],
....:                            [0, 0, 0, 0, 0, 1, 0, 1, 1],
....:                            [0, 0, 0, 0, 0, 0, 1, 1, 1]])
sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode(M); node
UnknownNode (9×9)
sage: C0 = node.complete_decomposition()
sage: unicode_art(C0)
╭OneSumNode (9×9) with 2 children─╮
│                                 │
ThreeConnectedIrregularNode (5×4) ThreeConnectedIrregularNode (4×5)
sage: C1, C2 = C0.child_nodes()
sage: C11 = C1.complete_decomposition(); C11
ThreeConnectedIrregularNode (5×4)
sage: unicode_art(C11)
ThreeConnectedIrregularNode (5×4)
sage: C1.matrix()
[1 1 0 0]
[1 1 1 0]
[0 1 1 1]
[1 0 0 1]
[0 0 1 1]
sage: C11.matrix()
[1 1 0 0]
[1 1 1 0]
[0 1 1 1]
[1 0 0 1]
[0 0 1 1]
sage: C22 = C2.complete_decomposition(); C22
ThreeConnectedIrregularNode (4×5)
sage: unicode_art(C22)
ThreeConnectedIrregularNode (4×5)
sage: C2.matrix()
[1 1 1 0 0]
[0 0 1 1 1]
[0 1 0 1 1]
[1 1 0 1 0]
sage: C22.matrix()
[1 1 1 0 0]
[0 0 1 1 1]
[0 1 0 1 1]
[1 1 0 1 0]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(9), sparse=True),
...                           [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0), Integer(1), Integer(1)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)]])
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode(M); node
UnknownNode (9×9)
>>> C0 = node.complete_decomposition()
>>> unicode_art(C0)
╭OneSumNode (9×9) with 2 children─╮
│                                 │
ThreeConnectedIrregularNode (5×4) ThreeConnectedIrregularNode (4×5)
>>> C1, C2 = C0.child_nodes()
>>> C11 = C1.complete_decomposition(); C11
ThreeConnectedIrregularNode (5×4)
>>> unicode_art(C11)
ThreeConnectedIrregularNode (5×4)
>>> C1.matrix()
[1 1 0 0]
[1 1 1 0]
[0 1 1 1]
[1 0 0 1]
[0 0 1 1]
>>> C11.matrix()
[1 1 0 0]
[1 1 1 0]
[0 1 1 1]
[1 0 0 1]
[0 0 1 1]
>>> C22 = C2.complete_decomposition(); C22
ThreeConnectedIrregularNode (4×5)
>>> unicode_art(C22)
ThreeConnectedIrregularNode (4×5)
>>> C2.matrix()
[1 1 1 0 0]
[0 0 1 1 1]
[0 1 0 1 1]
[1 1 0 1 0]
>>> C22.matrix()
[1 1 1 0 0]
[0 0 1 1 1]
[0 1 0 1 1]
[1 1 0 1 0]
dimensions()[source]

Return the number of rows and columns of this node.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.dimensions()
(3, 2)

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, 1], [0, 1]]); node
UnknownNode (2×2)
sage: node.dimensions()
(2, 2)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.dimensions()
(3, 2)

>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), Integer(1)], [Integer(0), Integer(1)]]); node
UnknownNode (2×2)
>>> node.dimensions()
(2, 2)
is_conetwork_matrix(decomposition=False, **kwds)[source]

Return whether the matrix self over \(\GF{3}\) or \(\QQ\) is a conetwork matrix. If there is some entry not in \(\{-1, 0, 1\}\), return False.

This method is based on Seymour’s decomposition. The decomposition will stop once being nonconetwork is detected. For direct conetwork matrix check,

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: from sage.matrix.seymour_decomposition import DecompositionNode
sage: A = matrix(ZZ, [[-1, 0, 0, 0, 1,-1, 0],
....:                 [ 1, 0, 0, 1,-1, 1, 0],
....:                 [ 0,-1, 0,-1, 1,-1, 0],
....:                 [ 0, 1, 0, 0, 0, 0, 1],
....:                 [ 0, 0, 1,-1, 1, 0, 1],
....:                 [ 0, 0,-1, 1,-1, 0, 0]])
sage: M1 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 7, sparse=True), A)
sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 7, 6, sparse=True), A.transpose())
sage: M = Matrix_cmr_chr_sparse.one_sum(M1, M2)
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                         row_keys=[f'r{i}' for i in range(13)],
....:                         column_keys=[f'c{i}' for i in range(13)])
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())

sage: result, decomposition = node.is_conetwork_matrix(decomposition=True)
sage: unicode_art(decomposition)
╭─────────OneSumNode (13×13) with 2 children
│                │
PlanarNode (6×7) PlanarNode (7×6)
sage: node._cographicness()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is cographic/conetwork

sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 9, sparse=True),
....:                           [[1, 1, 0, 0, 0, 0, 0, 0, 0],
....:                            [-1,-1, 1, 0, 0, 0, 0, 0, 0],
....:                            [1, 0, 0, 1, 0, 0, 0, 0, 0],
....:                            [0, 1,-1,-1, 0, 0, 0, 0, 0],
....:                            [0, 0, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 0, 0, 1,-1, 1, 0, 0],
....:                            [0, 0, 0, 0, 1,-1, 0, 1, 0],
....:                            [0, 0, 0, 0, 0, 1, 0,-1, 1],
....:                            [0, 0, 0, 0, 0, 0, 1,-1, 1]])
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                         row_keys=[f'r{i}' for i in range(9)],
....:                         column_keys=[f'c{i}' for i in range(9)])
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())
sage: result, decomposition = node.is_conetwork_matrix(decomposition=True)
sage: result
False
sage: unicode_art(decomposition)
╭───────────OneSumNode (9×9) with 2 children
│                 │
GraphicNode (5×4) UnknownNode (4×5)
sage: decomposition.child_nodes()[1]._graphicness()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is graphic/network
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> from sage.matrix.seymour_decomposition import DecompositionNode
>>> A = matrix(ZZ, [[-Integer(1), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(0)],
...                 [ Integer(1), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0)],
...                 [ Integer(0),-Integer(1), Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0)],
...                 [ Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1)],
...                 [ Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0), Integer(1)],
...                 [ Integer(0), Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0), Integer(0)]])
>>> M1 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(7), sparse=True), A)
>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(7), Integer(6), sparse=True), A.transpose())
>>> M = Matrix_cmr_chr_sparse.one_sum(M1, M2)
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                         row_keys=[f'r{i}' for i in range(Integer(13))],
...                         column_keys=[f'c{i}' for i in range(Integer(13))])
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())

>>> result, decomposition = node.is_conetwork_matrix(decomposition=True)
>>> unicode_art(decomposition)
╭─────────OneSumNode (13×13) with 2 children
│                │
PlanarNode (6×7) PlanarNode (7×6)
>>> node._cographicness()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is cographic/conetwork

>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(9), sparse=True),
...                           [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [-Integer(1),-Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1),-Integer(1),-Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(0), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0),-Integer(1), Integer(1)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1)]])
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                         row_keys=[f'r{i}' for i in range(Integer(9))],
...                         column_keys=[f'c{i}' for i in range(Integer(9))])
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())
>>> result, decomposition = node.is_conetwork_matrix(decomposition=True)
>>> result
False
>>> unicode_art(decomposition)
╭───────────OneSumNode (9×9) with 2 children
│                 │
GraphicNode (5×4) UnknownNode (4×5)
>>> decomposition.child_nodes()[Integer(1)]._graphicness()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is graphic/network
is_network_matrix(decomposition=False, **kwds)[source]

Return whether the matrix self over \(\GF{3}\) or \(\QQ\) is a network matrix. If there is some entry not in \(\{-1, 0, 1\}\), return False.

This method is based on Seymour’s decomposition. The decomposition will stop once being nonnetwork is detected. For direct network matrix check,

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: from sage.matrix.seymour_decomposition import DecompositionNode
sage: A = matrix(ZZ, [[-1, 0, 0, 0, 1,-1, 0],
....:                 [ 1, 0, 0, 1,-1, 1, 0],
....:                 [ 0,-1, 0,-1, 1,-1, 0],
....:                 [ 0, 1, 0, 0, 0, 0, 1],
....:                 [ 0, 0, 1,-1, 1, 0, 1],
....:                 [ 0, 0,-1, 1,-1, 0, 0]])
sage: M1 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 7, sparse=True), A)
sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 7, 6, sparse=True), A.transpose())
sage: M = Matrix_cmr_chr_sparse.one_sum(M1, M2)
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                         row_keys=[f'r{i}' for i in range(13)],
....:                         column_keys=[f'c{i}' for i in range(13)])
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())

sage: result, decomposition = node.is_network_matrix(decomposition=True)
sage: unicode_art(decomposition)
╭─────────OneSumNode (13×13) with 2 children
│                │
PlanarNode (6×7) PlanarNode (7×6)
sage: node._graphicness()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is graphic/network

sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 9, sparse=True),
....:                           [[1, 1, 0, 0, 0, 0, 0, 0, 0],
....:                            [-1,-1, 1, 0, 0, 0, 0, 0, 0],
....:                            [1, 0, 0, 1, 0, 0, 0, 0, 0],
....:                            [0, 1,-1,-1, 0, 0, 0, 0, 0],
....:                            [0, 0, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 0, 0, 1,-1, 1, 0, 0],
....:                            [0, 0, 0, 0, 1,-1, 0, 1, 0],
....:                            [0, 0, 0, 0, 0, 1, 0,-1, 1],
....:                            [0, 0, 0, 0, 0, 0, 1,-1, 1]])
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                         row_keys=[f'r{i}' for i in range(9)],
....:                         column_keys=[f'c{i}' for i in range(9)])
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())
sage: result, decomposition = node.is_network_matrix(decomposition=True)
sage: result
False
sage: unicode_art(decomposition)
╭───────────OneSumNode (9×9) with 2 children
│                 │
GraphicNode (5×4) UnknownNode (4×5)
sage: decomposition.child_nodes()[1]._graphicness()
False
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> from sage.matrix.seymour_decomposition import DecompositionNode
>>> A = matrix(ZZ, [[-Integer(1), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(0)],
...                 [ Integer(1), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0)],
...                 [ Integer(0),-Integer(1), Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0)],
...                 [ Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1)],
...                 [ Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0), Integer(1)],
...                 [ Integer(0), Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0), Integer(0)]])
>>> M1 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(7), sparse=True), A)
>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(7), Integer(6), sparse=True), A.transpose())
>>> M = Matrix_cmr_chr_sparse.one_sum(M1, M2)
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                         row_keys=[f'r{i}' for i in range(Integer(13))],
...                         column_keys=[f'c{i}' for i in range(Integer(13))])
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())

>>> result, decomposition = node.is_network_matrix(decomposition=True)
>>> unicode_art(decomposition)
╭─────────OneSumNode (13×13) with 2 children
│                │
PlanarNode (6×7) PlanarNode (7×6)
>>> node._graphicness()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is graphic/network

>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(9), sparse=True),
...                           [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [-Integer(1),-Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1),-Integer(1),-Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(0), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0),-Integer(1), Integer(1)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1)]])
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                         row_keys=[f'r{i}' for i in range(Integer(9))],
...                         column_keys=[f'c{i}' for i in range(Integer(9))])
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())
>>> result, decomposition = node.is_network_matrix(decomposition=True)
>>> result
False
>>> unicode_art(decomposition)
╭───────────OneSumNode (9×9) with 2 children
│                 │
GraphicNode (5×4) UnknownNode (4×5)
>>> decomposition.child_nodes()[Integer(1)]._graphicness()
False
is_ternary()[source]

Return whether the decomposition is over \(\GF{3}\).

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.is_ternary()
True

sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [1, 1], [0, 1]]); M
[1  0]
[1  1]
[0  1]
sage: result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.is_ternary()
False
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.is_ternary()
True

>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[1  0]
[1  1]
[0  1]
>>> result, certificate = M._is_binary_linear_matroid_regular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.is_ternary()
False
is_totally_unimodular(decomposition=False, **kwds)[source]

Return whether self is a totally unimodular matrix.

A matrix is totally unimodular if every subdeterminant is \(0\), \(1\), or \(-1\).

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: from sage.matrix.seymour_decomposition import DecompositionNode
sage: A = matrix(ZZ, [[-1, 0, 0, 0, 1,-1, 0],
....:                 [ 1, 0, 0, 1,-1, 1, 0],
....:                 [ 0,-1, 0,-1, 1,-1, 0],
....:                 [ 0, 1, 0, 0, 0, 0, 1],
....:                 [ 0, 0, 1,-1, 1, 0, 1],
....:                 [ 0, 0,-1, 1,-1, 0, 0]])
sage: M1 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 7, sparse=True), A)
sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 7, 6, sparse=True), A.transpose())
sage: M = Matrix_cmr_chr_sparse.one_sum(M1, M2)
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                         row_keys=[f'r{i}' for i in range(13)],
....:                         column_keys=[f'c{i}' for i in range(13)])
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())

sage: result, decomposition = node.is_totally_unimodular(decomposition=True)
sage: unicode_art(decomposition)
╭─────────OneSumNode (13×13) with 2 children
│                │
PlanarNode (6×7) PlanarNode (7×6)
sage: node._regularity()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is regular/TU

sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 9, sparse=True),
....:                           [[1, 1, 0, 0, 0, 0, 0, 0, 0],
....:                            [-1,-1, 1, 0, 0, 0, 0, 0, 0],
....:                            [1, 0, 0, 1, 0, 0, 0, 0, 0],
....:                            [0, 1,-1,-1, 0, 0, 0, 0, 0],
....:                            [0, 0, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 0, 0, 1,-1, 1, 0, 0],
....:                            [0, 0, 0, 0, 1,-1, 0, 1, 0],
....:                            [0, 0, 0, 0, 0, 1, 0,-1, 1],
....:                            [0, 0, 0, 0, 0, 0, 1,-1, 1]])
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                         row_keys=[f'r{i}' for i in range(9)],
....:                         column_keys=[f'c{i}' for i in range(9)])
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())
sage: result, decomposition = node.is_totally_unimodular(decomposition=True)
sage: result
True
sage: unicode_art(decomposition)
╭───────────OneSumNode (9×9) with 2 children
│                 │
GraphicNode (5×4) CographicNode (4×5)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> from sage.matrix.seymour_decomposition import DecompositionNode
>>> A = matrix(ZZ, [[-Integer(1), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(0)],
...                 [ Integer(1), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0)],
...                 [ Integer(0),-Integer(1), Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0)],
...                 [ Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1)],
...                 [ Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0), Integer(1)],
...                 [ Integer(0), Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0), Integer(0)]])
>>> M1 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(7), sparse=True), A)
>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(7), Integer(6), sparse=True), A.transpose())
>>> M = Matrix_cmr_chr_sparse.one_sum(M1, M2)
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                         row_keys=[f'r{i}' for i in range(Integer(13))],
...                         column_keys=[f'c{i}' for i in range(Integer(13))])
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())

>>> result, decomposition = node.is_totally_unimodular(decomposition=True)
>>> unicode_art(decomposition)
╭─────────OneSumNode (13×13) with 2 children
│                │
PlanarNode (6×7) PlanarNode (7×6)
>>> node._regularity()
Traceback (most recent call last):
...
ValueError: It is not determined whether the decomposition node is regular/TU

>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(9), sparse=True),
...                           [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [-Integer(1),-Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1),-Integer(1),-Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(0), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0),-Integer(1), Integer(1)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1),-Integer(1), Integer(1)]])
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                         row_keys=[f'r{i}' for i in range(Integer(9))],
...                         column_keys=[f'c{i}' for i in range(Integer(9))])
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())
>>> result, decomposition = node.is_totally_unimodular(decomposition=True)
>>> result
True
>>> unicode_art(decomposition)
╭───────────OneSumNode (9×9) with 2 children
│                 │
GraphicNode (5×4) CographicNode (4×5)
matrix()[source]

Return a Matrix.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.matrix()
[ 1  0]
[-1  1]
[ 0  1]

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, 1], [0, 1]]); node
UnknownNode (2×2)
sage: node.matrix()
[1 1]
[0 1]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.matrix()
[ 1  0]
[-1  1]
[ 0  1]

>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), Integer(1)], [Integer(0), Integer(1)]]); node
UnknownNode (2×2)
>>> node.matrix()
[1 1]
[0 1]
minors()[source]

Return a tuple of minors of self.

Currently, it only handles determinant 2 submatrix.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 9, sparse=True),
....:                           [[1, 1, 0, 0, 0, 0, 0, 0, 0],
....:                            [1, 1, 1, 0, 0, 0, 0, 0, 0],
....:                            [1, 0, 0, 1, 0, 0, 0, 0, 0],
....:                            [0, 1, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 1, 1, 0, 0, 0, 0, 0],
....:                            [0, 0, 0, 0, 1, 1, 1, 0, 0],
....:                            [0, 0, 0, 0, 1, 1, 0, 1, 0],
....:                            [0, 0, 0, 0, 0, 1, 0, 1, 1],
....:                            [0, 0, 0, 0, 0, 0, 1, 1, 1]])
sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: C0 = UnknownNode(M).complete_decomposition()
sage: C1, C2 = C0.child_nodes()
sage: C1.minors()
(('|det| = 2 submatrix', ((4, 3, 1), (2, 3, 0))),)
sage: C2.minors()
(('|det| = 2 submatrix', ((2, 1, 0), (4, 2, 1))),)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(9), sparse=True),
...                           [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0), Integer(1), Integer(1)],
...                            [Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)]])
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> C0 = UnknownNode(M).complete_decomposition()
>>> C1, C2 = C0.child_nodes()
>>> C1.minors()
(('|det| = 2 submatrix', ((4, 3, 1), (2, 3, 0))),)
>>> C2.minors()
(('|det| = 2 submatrix', ((2, 1, 0), (4, 2, 1))),)
morphism()[source]

Create the matrix in the distinguished bases of the domain and codomain to build the module morphism.

See also: sage.modules.with_basis.morphism.ModuleMorphismFromMatrix.

EXAMPLES:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode(matrix(ZZ, [[1, 0, 1], [0, 1, 1]]),
....:                    row_keys='ab',
....:                    column_keys=range(3)); node
UnknownNode (2×3)
sage: node.matrix()
[1 0 1]
[0 1 1]
sage: node.morphism()._unicode_art_matrix()
  0 1 2
a⎛1 0 1⎞
b⎝0 1 1⎠
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode(matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]),
...                    row_keys='ab',
...                    column_keys=range(Integer(3))); node
UnknownNode (2×3)
>>> node.matrix()
[1 0 1]
[0 1 1]
>>> node.morphism()._unicode_art_matrix()
  0 1 2
a⎛1 0 1⎞
b⎝0 1 1⎠
nchildren()[source]

Return the number of children of the node.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.nchildren()
0
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.nchildren()
0
ncols()[source]

Return the number of columns of the internal matrix representing this node.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.nrows()
3
sage: certificate.ncols()
2

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, 1], [0, 1]]); node
UnknownNode (2×2)
sage: node.nrows()
2
sage: node.ncols()
2
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.nrows()
3
>>> certificate.ncols()
2

>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), Integer(1)], [Integer(0), Integer(1)]]); node
UnknownNode (2×2)
>>> node.nrows()
2
>>> node.ncols()
2
nminors()[source]

Return the number of minors of the node.

nrows()[source]

Return the number of rows of the internal matrix representing this node.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.nrows()
3
sage: certificate.ncols()
2

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, 1], [0, 1]]); node
UnknownNode (2×2)
sage: node.nrows()
2
sage: node.ncols()
2
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.nrows()
3
>>> certificate.ncols()
2

>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), Integer(1)], [Integer(0), Integer(1)]]); node
UnknownNode (2×2)
>>> node.nrows()
2
>>> node.ncols()
2
one_sum(*summands, **kwds)[source]

Return a OneSumNode constructed from the given nodes (summands).

INPUT:

  • summands – decomposition nodes DecompositionNode

  • summand_ids – a tuple or list of ids for summands

  • row_keys – a finite or enumerated family of arbitrary objects that index the rows of the result. Must be consistent with the row keys of the summands

  • column_keys – a finite or enumerated family of arbitrary objects that index the columns of the result. Must be consistent with the column keys of the summands

Note that row_keys, column_keys of summands are disjoint

OUTPUT: A OneSumNode

The terminology “1-sum” is used in the context of Seymour’s decomposition of totally unimodular matrices and regular matroids, see [Sch1986].

See also

two_sum() delta_sum(), three_sum(), y_sum()

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: from sage.matrix.seymour_decomposition import DecompositionNode
sage: M2 = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1, 1], [-1, 0]])
sage: result, certificate = M2.is_totally_unimodular(certificate=True,
....:                                                row_keys=range(4),
....:                                                column_keys='abcd')
sage: certificate
OneSumNode (4×4) with 2 children
sage: certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
sage: certificate.child_keys()
(((0, 1), ('a', 'b')), ((2, 3), ('c', 'd')))
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())
sage: node.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
sage: node.child_keys()
(((0, 1), ('a', 'b')), ((2, 3), ('c', 'd')))

sage: M3 = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1]], [[-1]])
sage: result, certificate = M3.is_totally_unimodular(certificate=True,
....:                                                row_keys=range(4),
....:                                                column_keys='abcd')
sage: certificate
OneSumNode (4×4) with 3 children
sage: certificate.summand_matrices()
(
[ 1  0]
[-1  1], [1], [-1]
)
sage: certificate.child_keys()
(((0, 1), ('a', 'b')), ((2,), ('c',)), ((3,), ('d',)))
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())
sage: node.summand_matrices()
(
[ 1  0]
[-1  1], [1], [-1]
)
sage: node.child_keys()
(((0, 1), ('a', 'b')), ((2,), ('c',)), ((3,), ('d',)))

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode(matrix(ZZ, [[1, 0, 1], [0, 1, 1]]),
....:                    row_keys='ab',
....:                    column_keys=range(3)); node
UnknownNode (2×3)
sage: node = DecompositionNode.one_sum(certificate, node, summand_ids=range(2))
sage: node.summand_matrices()
(
[ 1  0| 0| 0]
[-1  1| 0| 0]
[-----+--+--]
[ 0  0| 1| 0]
[-----+--+--]  [1 0 1]
[ 0  0| 0|-1], [0 1 1]
)
sage: node.child_keys()
((((0, 0), (0, 1), (0, 2), (0, 3)), ((0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'))),
 (((1, 'a'), (1, 'b')), ((1, 0), (1, 1), (1, 2))))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> from sage.matrix.seymour_decomposition import DecompositionNode
>>> M2 = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]])
>>> result, certificate = M2.is_totally_unimodular(certificate=True,
...                                                row_keys=range(Integer(4)),
...                                                column_keys='abcd')
>>> certificate
OneSumNode (4×4) with 2 children
>>> certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
>>> certificate.child_keys()
(((0, 1), ('a', 'b')), ((2, 3), ('c', 'd')))
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())
>>> node.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
>>> node.child_keys()
(((0, 1), ('a', 'b')), ((2, 3), ('c', 'd')))

>>> M3 = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1)]], [[-Integer(1)]])
>>> result, certificate = M3.is_totally_unimodular(certificate=True,
...                                                row_keys=range(Integer(4)),
...                                                column_keys='abcd')
>>> certificate
OneSumNode (4×4) with 3 children
>>> certificate.summand_matrices()
(
[ 1  0]
[-1  1], [1], [-1]
)
>>> certificate.child_keys()
(((0, 1), ('a', 'b')), ((2,), ('c',)), ((3,), ('d',)))
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())
>>> node.summand_matrices()
(
[ 1  0]
[-1  1], [1], [-1]
)
>>> node.child_keys()
(((0, 1), ('a', 'b')), ((2,), ('c',)), ((3,), ('d',)))

>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode(matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]),
...                    row_keys='ab',
...                    column_keys=range(Integer(3))); node
UnknownNode (2×3)
>>> node = DecompositionNode.one_sum(certificate, node, summand_ids=range(Integer(2)))
>>> node.summand_matrices()
(
[ 1  0| 0| 0]
[-1  1| 0| 0]
[-----+--+--]
[ 0  0| 1| 0]
[-----+--+--]  [1 0 1]
[ 0  0| 0|-1], [0 1 1]
)
>>> node.child_keys()
((((0, 0), (0, 1), (0, 2), (0, 3)), ((0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'))),
 (((1, 'a'), (1, 'b')), ((1, 0), (1, 1), (1, 2))))

row_keys, column_keys of summands are disjoint:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: from sage.matrix.seymour_decomposition import DecompositionNode
sage: M2 = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1, 1], [-1, 0]])
sage: result, certificate = M2.is_totally_unimodular(certificate=True,
....:                                                row_keys='aefg',
....:                                                column_keys='abcd')
sage: node = DecompositionNode.one_sum(*certificate.child_nodes())
Traceback (most recent call last):
...
ValueError: keys must be disjoint, got
summand_row_keys=('a', 'e'), summand_column_keys=('a', 'b')

sage: result, certificate = M2.is_totally_unimodular(certificate=True,
....:                                                row_keys=range(4),
....:                                                column_keys='abcd')
sage: node = DecompositionNode.one_sum(*certificate.child_nodes(),
....:                                  row_keys=range(4),
....:                                  column_keys='abce')
Traceback (most recent call last):
...
ValueError: inconsistent column_keys, got column_keys=('a', 'b', 'c', 'e'),
should be a permutation of ['a', 'b', 'c', 'd']
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> from sage.matrix.seymour_decomposition import DecompositionNode
>>> M2 = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]])
>>> result, certificate = M2.is_totally_unimodular(certificate=True,
...                                                row_keys='aefg',
...                                                column_keys='abcd')
>>> node = DecompositionNode.one_sum(*certificate.child_nodes())
Traceback (most recent call last):
...
ValueError: keys must be disjoint, got
summand_row_keys=('a', 'e'), summand_column_keys=('a', 'b')

>>> result, certificate = M2.is_totally_unimodular(certificate=True,
...                                                row_keys=range(Integer(4)),
...                                                column_keys='abcd')
>>> node = DecompositionNode.one_sum(*certificate.child_nodes(),
...                                  row_keys=range(Integer(4)),
...                                  column_keys='abce')
Traceback (most recent call last):
...
ValueError: inconsistent column_keys, got column_keys=('a', 'b', 'c', 'e'),
should be a permutation of ['a', 'b', 'c', 'd']
plot(**kwds)[source]

Plot the decomposition tree rooted at self.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = matrix([[1, 0], [-1, 1], [0, 1]], sparse=True)
sage: M2MT = block_diagonal_matrix([M, M, M.T], sparse=True)
sage: M2MTcmr = Matrix_cmr_chr_sparse(M2MT.parent(), M2MT)
sage: result, certificate = M2MTcmr.is_totally_unimodular(certificate=True)
sage: T = certificate.as_ordered_tree()
sage: T.plot()                                                              # needs sage.plot
Graphics object consisting of 8 graphics primitives
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = matrix([[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]], sparse=True)
>>> M2MT = block_diagonal_matrix([M, M, M.T], sparse=True)
>>> M2MTcmr = Matrix_cmr_chr_sparse(M2MT.parent(), M2MT)
>>> result, certificate = M2MTcmr.is_totally_unimodular(certificate=True)
>>> T = certificate.as_ordered_tree()
>>> T.plot()                                                              # needs sage.plot
Graphics object consisting of 8 graphics primitives
row_keys()[source]

Return the row keys of this node.

OUTPUT: a tuple or None

EXAMPLES:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode(matrix(ZZ, [[1, 0, 1], [0, 1, 1]]),
....:                    row_keys='ab',
....:                    column_keys=range(3)); node
UnknownNode (2×3)
sage: node.row_keys()
('a', 'b')
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode(matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]),
...                    row_keys='ab',
...                    column_keys=range(Integer(3))); node
UnknownNode (2×3)
>>> node.row_keys()
('a', 'b')
set_default_keys()[source]

Set default row and column keys.

See also

ElementKey

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0, 1]]); M
[ 1  0]
[-1  1]
[ 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, GraphicNode (3×2))
sage: certificate.row_keys() is None
True
sage: certificate.set_default_keys()
sage: certificate.row_keys()
(r0, r1, r2)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, GraphicNode (3×2))
>>> certificate.row_keys() is None
True
>>> certificate.set_default_keys()
>>> certificate.row_keys()
(r0, r1, r2)
class sage.matrix.seymour_decomposition.DeltaSumNode[source]

Bases: SumNode

block_matrix_form()[source]

Return the block matrix constructed from the \(\Delta\)-sum of children.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 6, sparse=True),
....: [[1,0,1,1,0,0],[0,1,1,1,0,0],[1,0,1,0,1,1],
....: [0,-1,0,-1,1,1],[1,0,1,0,1,0],[0,-1,0,-1,0,1]])
sage: R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="delta_pivot")
sage: C = certificate.child_nodes()[0]; C
DeltaSumNode (6×6)
sage: C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
sage: C.summand_matrices()
(
[ 0  0  1  1  1]  [-1  0  1 -1 -1]
[ 1  1  1  0  0]  [ 1  1  0  1  1]
[ 0  1  0 -1 -1]  [ 0  0  1  0 -1]
[-1  0 -1  0 -1], [ 1  1  0  0  1]
)
sage: C.row_keys()
(r0, r1, c0, r3, r4, r5)
sage: C.column_keys()
(r2, c1, c2, c3, c4, c5)
sage: C.child_keys()
(((r0, r1, c0, r3), (c1, c2, c3, r2, +r2-r3)),
 ((r0, r3, r4, r5), (+c1-r0, c1, r2, c4, c5)))
sage: C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(6), sparse=True),
... [[Integer(1),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)],
... [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)]])
>>> R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="delta_pivot")
>>> C = certificate.child_nodes()[Integer(0)]; C
DeltaSumNode (6×6)
>>> C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
>>> C.summand_matrices()
(
[ 0  0  1  1  1]  [-1  0  1 -1 -1]
[ 1  1  1  0  0]  [ 1  1  0  1  1]
[ 0  1  0 -1 -1]  [ 0  0  1  0 -1]
[-1  0 -1  0 -1], [ 1  1  0  0  1]
)
>>> C.row_keys()
(r0, r1, c0, r3, r4, r5)
>>> C.column_keys()
(r2, c1, c2, c3, c4, c5)
>>> C.child_keys()
(((r0, r1, c0, r3), (c1, c2, c3, r2, +r2-r3)),
 ((r0, r3, r4, r5), (+c1-r0, c1, r2, c4, c5)))
>>> C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
is_concentrated_rank()[source]

Return False for the \(\Delta\)-sum node self.

concentrated_rank is named after the rank 2 and rank 0 off-diagonal blocks.

is_distributed_ranks()[source]

Return True for the \(\Delta\)-sum node self.

distributed_ranks is named after the two rank 1 off-diagonal blocks.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12_large = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 12, sparse=True),
....:                 [[ 1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1],
....:                  [ 0,  0,  0,  1, -1,  0,  0,  0,  1,  1,  1,  1],
....:                  [ 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1],
....:                  [ 1,  0,  1,  0,  0,  0,  0,  0,  1,  1,  0,  0],
....:                  [ 0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1, -1],
....:                  [ 0,  0,  0,  1,  0,  1,  0,  0,  1,  1,  0,  0],
....:                  [ 0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1, -1],
....:                  [ 0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0],
....:                  [ 0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1]])
sage: result, certificate = R12_large.is_totally_unimodular(certificate=True,
....:                                 decompose_strategy="delta_pivot")
sage: C = certificate.child_nodes()[0]; C
DeltaSumNode (9×12)
sage: C.is_distributed_ranks()
True
sage: C.is_concentrated_rank()
False
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12_large = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(12), sparse=True),
...                 [[ Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...                  [ Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1)]])
>>> result, certificate = R12_large.is_totally_unimodular(certificate=True,
...                                 decompose_strategy="delta_pivot")
>>> C = certificate.child_nodes()[Integer(0)]; C
DeltaSumNode (9×12)
>>> C.is_distributed_ranks()
True
>>> C.is_concentrated_rank()
False
permuted_block_matrix()[source]

Return the permutation matrices between the matrix and the block matrix form.

OUTPUT: a tuple (Prow, BlockMatrix, Pcolumn), where self.matrix() == Prow * BlockMatrix * Pcolumn, and BlockMatrix == self.block_matrix_form().

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 6, sparse=True),
....: [[1,0,1,1,0,0],[0,1,1,1,0,0],[1,0,1,0,1,1],
....: [0,-1,0,-1,1,1],[1,0,1,0,1,0],[0,-1,0,-1,0,1]])
sage: R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="delta_pivot")
sage: C = certificate.child_nodes()[0]; C
DeltaSumNode (6×6)
sage: C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
sage: C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
sage: P_row, block_matrix, P_column = C.permuted_block_matrix()
sage: P_row^(-1) * C.matrix() * P_column^(-1) == block_matrix
True
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(6), sparse=True),
... [[Integer(1),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)],
... [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)]])
>>> R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="delta_pivot")
>>> C = certificate.child_nodes()[Integer(0)]; C
DeltaSumNode (6×6)
>>> C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
>>> C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
>>> P_row, block_matrix, P_column = C.permuted_block_matrix()
>>> P_row**(-Integer(1)) * C.matrix() * P_column**(-Integer(1)) == block_matrix
True
class sage.matrix.seymour_decomposition.ElementKey[source]

Bases: object

Create the element key for a row or column index of DecompositionNode.

INPUT:

  • keys – a row/column key or a tuple (\(\pm 1\), row/column key, \(\pm 1\), row/column key).

  • compositionTrue or False (default). whether the key is a composition key or not. If False, self._key is a frozenset with a row/column key. If True, self._key is a frozenset with two tuples, where each tuple has a sign value and a row/column key. For example, frozenset((1,'a'), (-1,'7')).

key
class sage.matrix.seymour_decomposition.GraphicNode[source]

Bases: BaseGraphicNode

class sage.matrix.seymour_decomposition.OneSumNode[source]

Bases: SumNode

block_matrix_form()[source]

Return the block matrix representing the one sum node.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]], [[1, 1], [-1, 0]])
sage: result, certificate = M.is_totally_unimodular(certificate=True); certificate
OneSumNode (4×4) with 2 children
sage: certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
sage: certificate.block_matrix_form()
[ 1  0| 0  0]
[-1  1| 0  0]
[-----+-----]
[ 0  0| 1  1]
[ 0  0|-1  0]

sage: M3 = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1, 1], [-1, 0]],
....:                                    [[1, 0], [0, 1]]); M3
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
sage: result, certificate = M3.is_totally_unimodular(certificate=True); certificate
OneSumNode (6×6) with 4 children
sage: certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0], [1], [1]
)
sage: certificate.block_matrix_form()
[ 1  0| 0  0| 0| 0]
[-1  1| 0  0| 0| 0]
[-----+-----+--+--]
[ 0  0| 1  1| 0| 0]
[ 0  0|-1  0| 0| 0]
[-----+-----+--+--]
[ 0  0| 0  0| 1| 0]
[-----+-----+--+--]
[ 0  0| 0  0| 0| 1]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]], [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]])
>>> result, certificate = M.is_totally_unimodular(certificate=True); certificate
OneSumNode (4×4) with 2 children
>>> certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
>>> certificate.block_matrix_form()
[ 1  0| 0  0]
[-1  1| 0  0]
[-----+-----]
[ 0  0| 1  1]
[ 0  0|-1  0]

>>> M3 = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]],
...                                    [[Integer(1), Integer(0)], [Integer(0), Integer(1)]]); M3
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
>>> result, certificate = M3.is_totally_unimodular(certificate=True); certificate
OneSumNode (6×6) with 4 children
>>> certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0], [1], [1]
)
>>> certificate.block_matrix_form()
[ 1  0| 0  0| 0| 0]
[-1  1| 0  0| 0| 0]
[-----+-----+--+--]
[ 0  0| 1  1| 0| 0]
[ 0  0|-1  0| 0| 0]
[-----+-----+--+--]
[ 0  0| 0  0| 1| 0]
[-----+-----+--+--]
[ 0  0| 0  0| 0| 1]
static check(result_matrix, summand_matrices, summand_parent_rows_and_columns)[source]

Check that result_matrix is a 1-sum of summand_matrices.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: from sage.matrix.seymour_decomposition import OneSumNode

sage: M2 = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1, 1], [-1, 0]])
sage: result, certificate = M2.is_totally_unimodular(certificate=True); certificate
OneSumNode (4×4) with 2 children
sage: OneSumNode.check(M2,
....:                  certificate.summand_matrices(),
....:                  certificate.child_keys())
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> from sage.matrix.seymour_decomposition import OneSumNode

>>> M2 = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]])
>>> result, certificate = M2.is_totally_unimodular(certificate=True); certificate
OneSumNode (4×4) with 2 children
>>> OneSumNode.check(M2,
...                  certificate.summand_matrices(),
...                  certificate.child_keys())

Symbolic identities:

sage: from sage.matrix.seymour_decomposition import OneSumNode
sage: R.<x,y> = QQ[]
sage: A = matrix([[x, 0], [-x, 1]])
sage: B = matrix([[x, y], [-x, 0]])
sage: A1B = block_diagonal_matrix([A, B])
sage: OneSumNode.check(A1B, [A, B], [([0, 1], [0, 1]),
....:                                ([2, 3], [2, 3])])
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import OneSumNode
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> A = matrix([[x, Integer(0)], [-x, Integer(1)]])
>>> B = matrix([[x, y], [-x, Integer(0)]])
>>> A1B = block_diagonal_matrix([A, B])
>>> OneSumNode.check(A1B, [A, B], [([Integer(0), Integer(1)], [Integer(0), Integer(1)]),
...                                ([Integer(2), Integer(3)], [Integer(2), Integer(3)])])

Using program analysis:

sage: # optional - cutgeneratingfunctionology
sage: R.<x,y,z> = ParametricRealField({x: 1}, {y: -1}, {z: 0})  # true example
sage: A = matrix([[x, 0], [-x, 1]])
sage: B = matrix([[x, y], [-x, 0]])
sage: A1B = matrix([[z, 0, 0, 0], [-x, z, 0, 0], [], []])
sage: OneSumNode.check(A1B, [A, B], [([0, 1], [0, 1]),
....:                                ([2, 3], [2, 3])])
sage: # side-effect: R stores polynomial identities
>>> from sage.all import *
>>> # optional - cutgeneratingfunctionology
>>> R = ParametricRealField({x: Integer(1)}, {y: -Integer(1)}, {z: Integer(0)}, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)# true example
>>> A = matrix([[x, Integer(0)], [-x, Integer(1)]])
>>> B = matrix([[x, y], [-x, Integer(0)]])
>>> A1B = matrix([[z, Integer(0), Integer(0), Integer(0)], [-x, z, Integer(0), Integer(0)], [], []])
>>> OneSumNode.check(A1B, [A, B], [([Integer(0), Integer(1)], [Integer(0), Integer(1)]),
...                                ([Integer(2), Integer(3)], [Integer(2), Integer(3)])])
>>> # side-effect: R stores polynomial identities
class sage.matrix.seymour_decomposition.PivotsNode[source]

Bases: DecompositionNode

npivots()[source]

Return the number of pivots in self.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 12, sparse=True),
....:           [[ 1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1],
....:            [ 0,  0,  0,  1, -1,  0,  0,  0,  1,  1,  1,  1],
....:            [ 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1],
....:            [ 1,  0,  1,  0,  0,  0,  0,  0,  1,  1,  0,  0],
....:            [ 0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1, -1],
....:            [ 0,  0,  0,  1,  0,  1,  0,  0,  1,  1,  0,  0],
....:            [ 0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1, -1],
....:            [ 0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0],
....:            [ 0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1]])
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="delta_pivot")
sage: certificate
PivotsNode (9×12)
sage: certificate.npivots()
1
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(12), sparse=True),
...           [[ Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...            [ Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1)]])
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="delta_pivot")
>>> certificate
PivotsNode (9×12)
>>> certificate.npivots()
1
pivot_rows_and_columns()[source]

Return a tuple of the row and column indices of all pivot entries.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 12, sparse=True),
....:           [[ 1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1],
....:            [ 0,  0,  0,  1, -1,  0,  0,  0,  1,  1,  1,  1],
....:            [ 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1],
....:            [ 1,  0,  1,  0,  0,  0,  0,  0,  1,  1,  0,  0],
....:            [ 0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1, -1],
....:            [ 0,  0,  0,  1,  0,  1,  0,  0,  1,  1,  0,  0],
....:            [ 0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1, -1],
....:            [ 0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0],
....:            [ 0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1]])
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="delta_pivot")
sage: certificate
PivotsNode (9×12)
sage: certificate.pivot_rows_and_columns()
((0, 8),)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(12), sparse=True),
...           [[ Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...            [ Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...            [ Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0)],
...            [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1)]])
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="delta_pivot")
>>> certificate
PivotsNode (9×12)
>>> certificate.pivot_rows_and_columns()
((0, 8),)
class sage.matrix.seymour_decomposition.PlanarNode[source]

Bases: BaseGraphicNode

cograph()[source]

Return the cograph of matrix.

EXAMPLES:

Undirected graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [1, 1], [0,1]]); M
[1 0]
[1 1]
[0 1]
sage: result, certificate = M._is_binary_linear_matroid_regular(certificate=True,
....:                                           check_graphic_minors_planar=True)
sage: result, certificate
(True, PlanarNode (3×2))
sage: G = certificate.cograph(); G
Graph on 3 vertices
sage: G.vertices(sort=True)
[1, 2, 7]
sage: G.edges(sort=True)
[(1, 2, None), (1, 7, None), (2, 7, None)]
sage: certificate.cograph_forest_edges()
((1, 2), (7, 1))
sage: certificate.cograph_coforest_edges()
((1, 2), (2, 7), (7, 1))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [Integer(1), Integer(1)], [Integer(0),Integer(1)]]); M
[1 0]
[1 1]
[0 1]
>>> result, certificate = M._is_binary_linear_matroid_regular(certificate=True,
...                                           check_graphic_minors_planar=True)
>>> result, certificate
(True, PlanarNode (3×2))
>>> G = certificate.cograph(); G
Graph on 3 vertices
>>> G.vertices(sort=True)
[1, 2, 7]
>>> G.edges(sort=True)
[(1, 2, None), (1, 7, None), (2, 7, None)]
>>> certificate.cograph_forest_edges()
((1, 2), (7, 1))
>>> certificate.cograph_coforest_edges()
((1, 2), (2, 7), (7, 1))

Directed graph:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 3, 2, sparse=True),
....:                           [[1, 0], [-1, 1], [0,-1]]); M
[ 1  0]
[-1  1]
[ 0 -1]
sage: result, certificate = M.is_totally_unimodular(certificate=True,
....:                               check_graphic_minors_planar=True)
sage: result, certificate
(True, PlanarNode (3×2))
sage: G = certificate.cograph(); G
Digraph on 3 vertices
sage: G.vertices(sort=True)
[1, 2, 7]
sage: G.edges(sort=True)
[(1, 2, None), (1, 7, None), (2, 7, None), (7, 1, None)]
sage: certificate.cograph_forest_edges()
((1, 2), (1, 7))
sage: certificate.cograph_coforest_edges()
((1, 2), (2, 7), (7, 1))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(3), Integer(2), sparse=True),
...                           [[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0),-Integer(1)]]); M
[ 1  0]
[-1  1]
[ 0 -1]
>>> result, certificate = M.is_totally_unimodular(certificate=True,
...                               check_graphic_minors_planar=True)
>>> result, certificate
(True, PlanarNode (3×2))
>>> G = certificate.cograph(); G
Digraph on 3 vertices
>>> G.vertices(sort=True)
[1, 2, 7]
>>> G.edges(sort=True)
[(1, 2, None), (1, 7, None), (2, 7, None), (7, 1, None)]
>>> certificate.cograph_forest_edges()
((1, 2), (1, 7))
>>> certificate.cograph_coforest_edges()
((1, 2), (2, 7), (7, 1))
cograph_coforest_edges()[source]

Return the forest edges of the cograph of self.

cograph_forest_edges()[source]

Return the forest edges of the cograph of self.

class sage.matrix.seymour_decomposition.R10Node[source]

Bases: DecompositionNode

Special R10 Node. Only two possible 5 by 5 matrices up to row and column permutations and negations.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R10 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 5, 5, sparse=True),
....:                             [[1, 0, 0, 1, 1],
....:                              [1, 1, 0, 0, 1],
....:                              [0, 1, 1, 0, 1],
....:                              [0, 0, 1, 1, 1],
....:                              [1, 1, 1, 1, 1]]); R10
[1 0 0 1 1]
[1 1 0 0 1]
[0 1 1 0 1]
[0 0 1 1 1]
[1 1 1 1 1]
sage: result, certificate = R10.is_totally_unimodular(certificate=True)
sage: result
True
sage: R10.is_network_matrix()
False
sage: R10.is_conetwork_matrix()
False
sage: result, certificate = R10._is_binary_linear_matroid_regular(certificate=True)
sage: result
True
sage: certificate._is_binary_linear_matroid_graphic()
False
sage: certificate._is_binary_linear_matroid_cographic()
False

sage: R10 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 5, 5, sparse=True),
....:                             [[ 1,-1, 0, 0,-1],
....:                              [-1, 1,-1, 0, 0],
....:                              [ 0,-1, 1,-1, 0],
....:                              [ 0, 0,-1, 1,-1],
....:                              [-1, 0, 0,-1, 1]]); R10
[ 1 -1  0  0 -1]
[-1  1 -1  0  0]
[ 0 -1  1 -1  0]
[ 0  0 -1  1 -1]
[-1  0  0 -1  1]
sage: result, certificate = R10.is_totally_unimodular(certificate=True)
sage: result
True
sage: R10.is_network_matrix()
False
sage: R10.is_conetwork_matrix()
False

sage: R10 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 5, 5, sparse=True),
....:                             [[1, 1, 0, 0, 1],
....:                              [1, 1,-1, 0, 0],
....:                              [0, 1,-1,-1, 0],
....:                              [0, 0, 1, 1, 1],
....:                              [1, 0, 0, 1, 1]]); R10
[ 1  1  0  0  1]
[ 1  1 -1  0  0]
[ 0  1 -1 -1  0]
[ 0  0  1  1  1]
[ 1  0  0  1  1]
sage: result, certificate = R10.is_totally_unimodular(certificate=True)
sage: result
True
sage: R10.is_network_matrix()
False
sage: R10.is_conetwork_matrix()
False

sage: R10 = Matrix_cmr_chr_sparse(MatrixSpace(GF(2), 5, 5, sparse=True),
....:                             [[1, 1, 0, 0, 1],
....:                              [1, 1,-1, 0, 0],
....:                              [0, 1,-1,-1, 0],
....:                              [0, 0, 1, 1, 1],
....:                              [1, 0, 0, 1, 1]]); R10
[1 1 0 0 1]
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
sage: result, certificate = R10._is_binary_linear_matroid_regular(certificate=True)
sage: result
True
sage: certificate
R10Node (5×5) a reduced matrix representation of R10 matroid
sage: certificate._is_binary_linear_matroid_graphic()
False
sage: certificate._is_binary_linear_matroid_cographic()
False
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R10 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(5), Integer(5), sparse=True),
...                             [[Integer(1), Integer(0), Integer(0), Integer(1), Integer(1)],
...                              [Integer(1), Integer(1), Integer(0), Integer(0), Integer(1)],
...                              [Integer(0), Integer(1), Integer(1), Integer(0), Integer(1)],
...                              [Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
...                              [Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]]); R10
[1 0 0 1 1]
[1 1 0 0 1]
[0 1 1 0 1]
[0 0 1 1 1]
[1 1 1 1 1]
>>> result, certificate = R10.is_totally_unimodular(certificate=True)
>>> result
True
>>> R10.is_network_matrix()
False
>>> R10.is_conetwork_matrix()
False
>>> result, certificate = R10._is_binary_linear_matroid_regular(certificate=True)
>>> result
True
>>> certificate._is_binary_linear_matroid_graphic()
False
>>> certificate._is_binary_linear_matroid_cographic()
False

>>> R10 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(5), Integer(5), sparse=True),
...                             [[ Integer(1),-Integer(1), Integer(0), Integer(0),-Integer(1)],
...                              [-Integer(1), Integer(1),-Integer(1), Integer(0), Integer(0)],
...                              [ Integer(0),-Integer(1), Integer(1),-Integer(1), Integer(0)],
...                              [ Integer(0), Integer(0),-Integer(1), Integer(1),-Integer(1)],
...                              [-Integer(1), Integer(0), Integer(0),-Integer(1), Integer(1)]]); R10
[ 1 -1  0  0 -1]
[-1  1 -1  0  0]
[ 0 -1  1 -1  0]
[ 0  0 -1  1 -1]
[-1  0  0 -1  1]
>>> result, certificate = R10.is_totally_unimodular(certificate=True)
>>> result
True
>>> R10.is_network_matrix()
False
>>> R10.is_conetwork_matrix()
False

>>> R10 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(5), Integer(5), sparse=True),
...                             [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(1)],
...                              [Integer(1), Integer(1),-Integer(1), Integer(0), Integer(0)],
...                              [Integer(0), Integer(1),-Integer(1),-Integer(1), Integer(0)],
...                              [Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
...                              [Integer(1), Integer(0), Integer(0), Integer(1), Integer(1)]]); R10
[ 1  1  0  0  1]
[ 1  1 -1  0  0]
[ 0  1 -1 -1  0]
[ 0  0  1  1  1]
[ 1  0  0  1  1]
>>> result, certificate = R10.is_totally_unimodular(certificate=True)
>>> result
True
>>> R10.is_network_matrix()
False
>>> R10.is_conetwork_matrix()
False

>>> R10 = Matrix_cmr_chr_sparse(MatrixSpace(GF(Integer(2)), Integer(5), Integer(5), sparse=True),
...                             [[Integer(1), Integer(1), Integer(0), Integer(0), Integer(1)],
...                              [Integer(1), Integer(1),-Integer(1), Integer(0), Integer(0)],
...                              [Integer(0), Integer(1),-Integer(1),-Integer(1), Integer(0)],
...                              [Integer(0), Integer(0), Integer(1), Integer(1), Integer(1)],
...                              [Integer(1), Integer(0), Integer(0), Integer(1), Integer(1)]]); R10
[1 1 0 0 1]
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
>>> result, certificate = R10._is_binary_linear_matroid_regular(certificate=True)
>>> result
True
>>> certificate
R10Node (5×5) a reduced matrix representation of R10 matroid
>>> certificate._is_binary_linear_matroid_graphic()
False
>>> certificate._is_binary_linear_matroid_cographic()
False
class sage.matrix.seymour_decomposition.SeriesParallelReductionNode[source]

Bases: DecompositionNode

core()[source]

Return the core of self.

A SeriesParallelReductionNode indicates that \(M\) arises from a smaller matrix \(M'\) (called the core) by successively adding zero rows/columns, unit rows/columns or duplicates of existing rows/columns (potentially scaled with \(-1\)).

Note that such series-parallel reductions preserve total unimodularity and binary regularity.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 5, 6, sparse=True),
....:                           [[1, 1, 1, 1, 1, 0], [1, 1, 1, 0, 0, 0],
....:                            [1, 0, 1, 1, 0, 1], [1, 0, 0, 1, 1, 0],
....:                            [1, 1, 0, 0, 1, 0]]); M
[1 1 1 1 1 0]
[1 1 1 0 0 0]
[1 0 1 1 0 1]
[1 0 0 1 1 0]
[1 1 0 0 1 0]
sage: result, certificate = M.is_totally_unimodular(certificate=True)
sage: result, certificate
(True, SeriesParallelReductionNode (5×6))
sage: certificate.core()
[1 1 1 1 1]
[1 1 1 0 0]
[1 0 1 1 0]
[1 0 0 1 1]
[1 1 0 0 1]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(5), Integer(6), sparse=True),
...                           [[Integer(1), Integer(1), Integer(1), Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0)],
...                            [Integer(1), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1)], [Integer(1), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0)],
...                            [Integer(1), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0)]]); M
[1 1 1 1 1 0]
[1 1 1 0 0 0]
[1 0 1 1 0 1]
[1 0 0 1 1 0]
[1 1 0 0 1 0]
>>> result, certificate = M.is_totally_unimodular(certificate=True)
>>> result, certificate
(True, SeriesParallelReductionNode (5×6))
>>> certificate.core()
[1 1 1 1 1]
[1 1 1 0 0]
[1 0 1 1 0]
[1 0 0 1 1]
[1 1 0 0 1]
class sage.matrix.seymour_decomposition.SumNode[source]

Bases: DecompositionNode

Base class for 1-sum, 2-sum, and 3-sums (\(\Delta\)-sum, 3-sum, Y-sum) nodes in Seymour’s decomposition

permuted_block_matrix()[source]

Return the permutation matrices between the matrix and the block matrix form.

OUTPUT: a tuple (Prow, BlockMatrix, Pcolumn), where self.matrix() == Prow * BlockMatrix * Pcolumn, and BlockMatrix == self.block_matrix_form().

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse

sage: M = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1, 1], [-1, 0]],
....:                                    [[1, 0], [0, 1]]); M
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
sage: M_perm = M.matrix_from_rows_and_columns([2, 4, 3, 0, 5, 1],
....:                                         [0, 1, 3, 5, 4, 2]); M_perm
[ 0  0  1  0  0  1]
[ 0  0  0  0  1  0]
[ 0  0  0  0  0 -1]
[ 1  0  0  0  0  0]
[ 0  0  0  1  0  0]
[-1  1  0  0  0  0]
sage: result, certificate = M_perm.is_totally_unimodular(certificate=True)
sage: certificate
OneSumNode (6×6) with 4 children
sage: P_row, block_matrix, P_column = certificate.permuted_block_matrix()
sage: P_row^(-1) * M_perm * P_column^(-1) == block_matrix
True
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse

>>> M = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]],
...                                    [[Integer(1), Integer(0)], [Integer(0), Integer(1)]]); M
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
>>> M_perm = M.matrix_from_rows_and_columns([Integer(2), Integer(4), Integer(3), Integer(0), Integer(5), Integer(1)],
...                                         [Integer(0), Integer(1), Integer(3), Integer(5), Integer(4), Integer(2)]); M_perm
[ 0  0  1  0  0  1]
[ 0  0  0  0  1  0]
[ 0  0  0  0  0 -1]
[ 1  0  0  0  0  0]
[ 0  0  0  1  0  0]
[-1  1  0  0  0  0]
>>> result, certificate = M_perm.is_totally_unimodular(certificate=True)
>>> certificate
OneSumNode (6×6) with 4 children
>>> P_row, block_matrix, P_column = certificate.permuted_block_matrix()
>>> P_row**(-Integer(1)) * M_perm * P_column**(-Integer(1)) == block_matrix
True
summand_matrices()[source]

Return a tuple of matrices representing the child nodes.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M2 = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                    [[1, 1], [-1, 0]])
sage: result, certificate = M2.is_totally_unimodular(certificate=True,
....:                                                row_keys=range(4),
....:                                                column_keys='abcd')
sage: certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M2 = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                    [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]])
>>> result, certificate = M2.is_totally_unimodular(certificate=True,
...                                                row_keys=range(Integer(4)),
...                                                column_keys='abcd')
>>> certificate.summand_matrices()
(
[ 1  0]  [ 1  1]
[-1  1], [-1  0]
)
summands()[source]

Return a tuple of the children.

The children are sorted by the ordering inherited from cmr, which is their appearance in the parent.

In the case of SumNode, this is the same as summands().

For graphic or leaf nodes, it returns the empty tuple.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M = Matrix_cmr_chr_sparse.one_sum([[1, 0], [-1, 1]],
....:                                   [[1, 1], [-1, 0]],
....:                                   [[1, 0], [0,1]]); M
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
sage: result, certificate = M.is_totally_unimodular(certificate=True); certificate
OneSumNode (6×6) with 4 children
sage: certificate.child_nodes()
(GraphicNode (2×2), GraphicNode (2×2), GraphicNode (1×1), GraphicNode (1×1))

sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 2, 2, sparse=True),
....:                            [[1, 1], [-1, 0]]); M2
[ 1  1]
[-1  0]
sage: result, certificate = M2.is_totally_unimodular(certificate=True); certificate
GraphicNode (2×2)
sage: certificate.child_nodes()
()
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M = Matrix_cmr_chr_sparse.one_sum([[Integer(1), Integer(0)], [-Integer(1), Integer(1)]],
...                                   [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]],
...                                   [[Integer(1), Integer(0)], [Integer(0),Integer(1)]]); M
[ 1  0| 0  0| 0  0]
[-1  1| 0  0| 0  0]
[-----+-----+-----]
[ 0  0| 1  1| 0  0]
[ 0  0|-1  0| 0  0]
[-----+-----+-----]
[ 0  0| 0  0| 1  0]
[ 0  0| 0  0| 0  1]
>>> result, certificate = M.is_totally_unimodular(certificate=True); certificate
OneSumNode (6×6) with 4 children
>>> certificate.child_nodes()
(GraphicNode (2×2), GraphicNode (2×2), GraphicNode (1×1), GraphicNode (1×1))

>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(2), Integer(2), sparse=True),
...                            [[Integer(1), Integer(1)], [-Integer(1), Integer(0)]]); M2
[ 1  1]
[-1  0]
>>> result, certificate = M2.is_totally_unimodular(certificate=True); certificate
GraphicNode (2×2)
>>> certificate.child_nodes()
()
class sage.matrix.seymour_decomposition.ThreeConnectedIrregularNode[source]

Bases: DecompositionNode

class sage.matrix.seymour_decomposition.ThreeSumNode[source]

Bases: SumNode

block_matrix_form()[source]

Return the block matrix constructed from the 3-sum of children.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 6, sparse=True),
....: [[1,0,1,1,0,0],[0,1,1,1,0,0],[1,0,1,0,1,1],
....: [0,-1,0,-1,1,1],[1,0,1,0,1,0],[0,-1,0,-1,0,1]])
sage: R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="three_pivot")
sage: C = certificate; C
ThreeSumNode (6×6)
sage: C.matrix()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: C.summand_matrices()
(
                  [ 1  1  0  0]
[ 1  0  1  1  0]  [ 1  0  1  1]
[ 0  1  1  1  0]  [ 0 -1  1  1]
[ 1  0  1  0  1]  [ 1  0  1  0]
[ 0 -1  0 -1  1], [ 0 -1  0  1]
)
sage: C.child_keys()
(((r0, r1, r2, r3), (c0, c1, c2, c3, +r2+r3)),
((+c0+c3, r2, r3, r4, r5), (c0, c3, c4, c5)))
sage: C.block_matrix_form()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(6), sparse=True),
... [[Integer(1),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)],
... [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)]])
>>> R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="three_pivot")
>>> C = certificate; C
ThreeSumNode (6×6)
>>> C.matrix()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> C.summand_matrices()
(
                  [ 1  1  0  0]
[ 1  0  1  1  0]  [ 1  0  1  1]
[ 0  1  1  1  0]  [ 0 -1  1  1]
[ 1  0  1  0  1]  [ 1  0  1  0]
[ 0 -1  0 -1  1], [ 0 -1  0  1]
)
>>> C.child_keys()
(((r0, r1, r2, r3), (c0, c1, c2, c3, +r2+r3)),
((+c0+c3, r2, r3, r4, r5), (c0, c3, c4, c5)))
>>> C.block_matrix_form()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
is_concentrated_rank()[source]

Return True for the 3-sum node self.

concentrated_rank is named after the rank 2 and rank 0 off-diagonal blocks.

is_distributed_ranks()[source]

Return False for the 3-sum node self.

distributed_ranks is named after the two rank 1 off-diagonal blocks.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12_large = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 12, sparse=True),
....:                 [[ 1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1],
....:                  [ 0,  0,  0,  1, -1,  0,  0,  0,  1,  1,  1,  1],
....:                  [ 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1],
....:                  [ 1,  0,  1,  0,  0,  0,  0,  0,  1,  1,  0,  0],
....:                  [ 0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1, -1],
....:                  [ 0,  0,  0,  1,  0,  1,  0,  0,  1,  1,  0,  0],
....:                  [ 0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1, -1],
....:                  [ 0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0],
....:                  [ 0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1]])
sage: result, certificate = R12_large.is_totally_unimodular(certificate=True,
....:                                 decompose_strategy="three_pivot")
sage: C = certificate; C
ThreeSumNode (9×12)
sage: C.is_distributed_ranks()
False
sage: C.is_concentrated_rank()
True
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12_large = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(12), sparse=True),
...                 [[ Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...                  [ Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1)]])
>>> result, certificate = R12_large.is_totally_unimodular(certificate=True,
...                                 decompose_strategy="three_pivot")
>>> C = certificate; C
ThreeSumNode (9×12)
>>> C.is_distributed_ranks()
False
>>> C.is_concentrated_rank()
True
permuted_block_matrix()[source]

Return the permutation matrices between the matrix and the block matrix form.

OUTPUT: a tuple (Prow, BlockMatrix, Pcolumn), where self.matrix() == Prow * BlockMatrix * Pcolumn, and BlockMatrix == self.block_matrix_form().

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 6, sparse=True),
....: [[1,0,1,1,0,0],[0,1,1,1,0,0],[1,0,1,0,1,1],
....: [0,-1,0,-1,1,1],[1,0,1,0,1,0],[0,-1,0,-1,0,1]])
sage: R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="three_pivot")
sage: C = certificate; C
ThreeSumNode (6×6)
sage: C.matrix()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: C.block_matrix_form()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: P_row, block_matrix, P_column = C.permuted_block_matrix()
sage: P_row^(-1) * C.matrix() * P_column^(-1) == block_matrix
True
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(6), sparse=True),
... [[Integer(1),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)],
... [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)]])
>>> R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="three_pivot")
>>> C = certificate; C
ThreeSumNode (6×6)
>>> C.matrix()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> C.block_matrix_form()
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> P_row, block_matrix, P_column = C.permuted_block_matrix()
>>> P_row**(-Integer(1)) * C.matrix() * P_column**(-Integer(1)) == block_matrix
True
class sage.matrix.seymour_decomposition.TwoSumNode[source]

Bases: SumNode

block_matrix_form()[source]

Return the block matrix representing the two sum node.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 5, 5, sparse=True),
....:                            [[1, 1, 1, 1, 1], [1, 1, 1, 0, 0],
....:                             [1, 0, 1, 1, 0], [1, 0, 0, 1, 1],
....:                             [1, 1, 0, 0, 1]]); M2
[1 1 1 1 1]
[1 1 1 0 0]
[1 0 1 1 0]
[1 0 0 1 1]
[1 1 0 0 1]
sage: M3 = Matrix_cmr_chr_sparse.two_sum(M2, M2, 0, 1); M3
[1 1 1 1|1 1 1 0 0]
[1 1 0 0|1 1 1 0 0]
[0 1 1 0|1 1 1 0 0]
[0 0 1 1|1 1 1 0 0]
[1 0 0 1|1 1 1 0 0]
[-------+---------]
[0 0 0 0|1 1 1 1 1]
[0 0 0 0|1 0 1 1 0]
[0 0 0 0|1 0 0 1 1]
[0 0 0 0|1 1 0 0 1]
sage: result, certificate = M3.is_totally_unimodular(certificate=True); certificate
TwoSumNode (9×9)

sage: K33 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 5, 4, sparse=True),
....:                            [[1, 1, 0, 0], [1, 1, 1, 0],
....:                             [1, 0, 0,-1], [0, 1, 1, 1],
....:                             [0, 0, 1, 1]]); K33
[ 1  1  0  0]
[ 1  1  1  0]
[ 1  0  0 -1]
[ 0  1  1  1]
[ 0  0  1  1]
sage: K33_dual = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 4, 5, sparse=True),
....:                            [[1, 1, 1, 0, 0], [1, 1, 0, 1, 0],
....:                             [0, 1, 0, 1, 1], [0, 0,-1, 1, 1]]); K33_dual
[ 1  1  1  0  0]
[ 1  1  0  1  0]
[ 0  1  0  1  1]
[ 0  0 -1  1  1]
sage: M = Matrix_cmr_chr_sparse.two_sum(K33, K33_dual, 0, 0,
....:                                   nonzero_block="bottom_left"); M
[ 1  1  1  0| 0  0  0  0]
[ 1  0  0 -1| 0  0  0  0]
[ 0  1  1  1| 0  0  0  0]
[ 0  0  1  1| 0  0  0  0]
[-----------+-----------]
[ 1  1  0  0| 1  1  0  0]
[ 1  1  0  0| 1  0  1  0]
[ 0  0  0  0| 1  0  1  1]
[ 0  0  0  0| 0 -1  1  1]
sage: result1, certificate1 = M.is_totally_unimodular(certificate=True); certificate1
TwoSumNode (8×8)
sage: certificate1.summand_matrices()
(
[ 1  1  1  0]
[ 1  0  0 -1]  [ 1  1  1  0  0]
[ 0  1  1  1]  [ 1  1  0  1  0]
[ 0  0  1  1]  [ 0  1  0  1  1]
[ 1  1  0  0], [ 0  0 -1  1  1]
)
sage: certificate1.block_matrix_form()
[ 1  1  1  0| 0  0  0  0]
[ 1  0  0 -1| 0  0  0  0]
[ 0  1  1  1| 0  0  0  0]
[ 0  0  1  1| 0  0  0  0]
[-----------+-----------]
[ 1  1  0  0| 1  1  0  0]
[ 1  1  0  0| 1  0  1  0]
[ 0  0  0  0| 1  0  1  1]
[ 0  0  0  0| 0 -1  1  1]
sage: certificate1.child_keys()
(((0, 1, 2, 3, 4), (0, 1, 2, 3)), ((4, 5, 6, 7), (0, 4, 5, 6, 7)))
sage: M_perm = M.matrix_from_rows_and_columns([4, 6, 5, 7, 0, 1, 2, 3], range(M.ncols()))
sage: M_perm
[ 1  1  0  0  1  1  0  0]
[ 0  0  0  0  1  0  1  1]
[ 1  1  0  0  1  0  1  0]
[ 0  0  0  0  0 -1  1  1]
[ 1  1  1  0  0  0  0  0]
[ 1  0  0 -1  0  0  0  0]
[ 0  1  1  1  0  0  0  0]
[ 0  0  1  1  0  0  0  0]
sage: result2, certificate2 = M_perm.is_totally_unimodular(certificate=True)
sage: certificate2.summand_matrices()
(
[ 1  1  1  0]
[ 1  0  0 -1]  [ 1  1  1  0  0]
[ 0  1  1  1]  [ 0  1  0  1  1]
[ 0  0  1  1]  [ 1  1  0  1  0]
[ 1  1  0  0], [ 0  0 -1  1  1]
)
sage: certificate2.block_matrix_form()
[ 1  1  1  0| 0  0  0  0]
[ 1  0  0 -1| 0  0  0  0]
[ 0  1  1  1| 0  0  0  0]
[ 0  0  1  1| 0  0  0  0]
[-----------+-----------]
[ 1  1  0  0| 1  1  0  0]
[ 0  0  0  0| 1  0  1  1]
[ 1  1  0  0| 1  0  1  0]
[ 0  0  0  0| 0 -1  1  1]
sage: certificate2.child_keys()
(((4, 5, 6, 7, 0), (0, 1, 2, 3)), ((0, 1, 2, 3), (0, 4, 5, 6, 7)))
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> M2 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(5), Integer(5), sparse=True),
...                            [[Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)], [Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)],
...                             [Integer(1), Integer(0), Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0), Integer(0), Integer(1), Integer(1)],
...                             [Integer(1), Integer(1), Integer(0), Integer(0), Integer(1)]]); M2
[1 1 1 1 1]
[1 1 1 0 0]
[1 0 1 1 0]
[1 0 0 1 1]
[1 1 0 0 1]
>>> M3 = Matrix_cmr_chr_sparse.two_sum(M2, M2, Integer(0), Integer(1)); M3
[1 1 1 1|1 1 1 0 0]
[1 1 0 0|1 1 1 0 0]
[0 1 1 0|1 1 1 0 0]
[0 0 1 1|1 1 1 0 0]
[1 0 0 1|1 1 1 0 0]
[-------+---------]
[0 0 0 0|1 1 1 1 1]
[0 0 0 0|1 0 1 1 0]
[0 0 0 0|1 0 0 1 1]
[0 0 0 0|1 1 0 0 1]
>>> result, certificate = M3.is_totally_unimodular(certificate=True); certificate
TwoSumNode (9×9)

>>> K33 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(5), Integer(4), sparse=True),
...                            [[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(1), Integer(0)],
...                             [Integer(1), Integer(0), Integer(0),-Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)],
...                             [Integer(0), Integer(0), Integer(1), Integer(1)]]); K33
[ 1  1  0  0]
[ 1  1  1  0]
[ 1  0  0 -1]
[ 0  1  1  1]
[ 0  0  1  1]
>>> K33_dual = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(4), Integer(5), sparse=True),
...                            [[Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0), Integer(1), Integer(0)],
...                             [Integer(0), Integer(1), Integer(0), Integer(1), Integer(1)], [Integer(0), Integer(0),-Integer(1), Integer(1), Integer(1)]]); K33_dual
[ 1  1  1  0  0]
[ 1  1  0  1  0]
[ 0  1  0  1  1]
[ 0  0 -1  1  1]
>>> M = Matrix_cmr_chr_sparse.two_sum(K33, K33_dual, Integer(0), Integer(0),
...                                   nonzero_block="bottom_left"); M
[ 1  1  1  0| 0  0  0  0]
[ 1  0  0 -1| 0  0  0  0]
[ 0  1  1  1| 0  0  0  0]
[ 0  0  1  1| 0  0  0  0]
[-----------+-----------]
[ 1  1  0  0| 1  1  0  0]
[ 1  1  0  0| 1  0  1  0]
[ 0  0  0  0| 1  0  1  1]
[ 0  0  0  0| 0 -1  1  1]
>>> result1, certificate1 = M.is_totally_unimodular(certificate=True); certificate1
TwoSumNode (8×8)
>>> certificate1.summand_matrices()
(
[ 1  1  1  0]
[ 1  0  0 -1]  [ 1  1  1  0  0]
[ 0  1  1  1]  [ 1  1  0  1  0]
[ 0  0  1  1]  [ 0  1  0  1  1]
[ 1  1  0  0], [ 0  0 -1  1  1]
)
>>> certificate1.block_matrix_form()
[ 1  1  1  0| 0  0  0  0]
[ 1  0  0 -1| 0  0  0  0]
[ 0  1  1  1| 0  0  0  0]
[ 0  0  1  1| 0  0  0  0]
[-----------+-----------]
[ 1  1  0  0| 1  1  0  0]
[ 1  1  0  0| 1  0  1  0]
[ 0  0  0  0| 1  0  1  1]
[ 0  0  0  0| 0 -1  1  1]
>>> certificate1.child_keys()
(((0, 1, 2, 3, 4), (0, 1, 2, 3)), ((4, 5, 6, 7), (0, 4, 5, 6, 7)))
>>> M_perm = M.matrix_from_rows_and_columns([Integer(4), Integer(6), Integer(5), Integer(7), Integer(0), Integer(1), Integer(2), Integer(3)], range(M.ncols()))
>>> M_perm
[ 1  1  0  0  1  1  0  0]
[ 0  0  0  0  1  0  1  1]
[ 1  1  0  0  1  0  1  0]
[ 0  0  0  0  0 -1  1  1]
[ 1  1  1  0  0  0  0  0]
[ 1  0  0 -1  0  0  0  0]
[ 0  1  1  1  0  0  0  0]
[ 0  0  1  1  0  0  0  0]
>>> result2, certificate2 = M_perm.is_totally_unimodular(certificate=True)
>>> certificate2.summand_matrices()
(
[ 1  1  1  0]
[ 1  0  0 -1]  [ 1  1  1  0  0]
[ 0  1  1  1]  [ 0  1  0  1  1]
[ 0  0  1  1]  [ 1  1  0  1  0]
[ 1  1  0  0], [ 0  0 -1  1  1]
)
>>> certificate2.block_matrix_form()
[ 1  1  1  0| 0  0  0  0]
[ 1  0  0 -1| 0  0  0  0]
[ 0  1  1  1| 0  0  0  0]
[ 0  0  1  1| 0  0  0  0]
[-----------+-----------]
[ 1  1  0  0| 1  1  0  0]
[ 0  0  0  0| 1  0  1  1]
[ 1  1  0  0| 1  0  1  0]
[ 0  0  0  0| 0 -1  1  1]
>>> certificate2.child_keys()
(((4, 5, 6, 7, 0), (0, 1, 2, 3)), ((0, 1, 2, 3), (0, 4, 5, 6, 7)))
class sage.matrix.seymour_decomposition.UnknownNode[source]

Bases: DecompositionNode

EXAMPLES:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, 1], [0, 1]]); node
UnknownNode (2×2)
sage: node.matrix()
[1 1]
[0 1]
sage: node = UnknownNode(matrix(ZZ, [[1, 0, 1], [0, 1, 1]])); node
UnknownNode (2×3)
sage: node.matrix()
[1 0 1]
[0 1 1]
sage: node = UnknownNode(matrix(ZZ, [[1, 0, 1], [0, 1, 1]]),
....:                    row_keys='ab',
....:                    column_keys=range(3)); node
UnknownNode (2×3)
sage: node.matrix()
[1 0 1]
[0 1 1]
sage: node.morphism()._unicode_art_matrix()
  0 1 2
a⎛1 0 1⎞
b⎝0 1 1⎠
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), Integer(1)], [Integer(0), Integer(1)]]); node
UnknownNode (2×2)
>>> node.matrix()
[1 1]
[0 1]
>>> node = UnknownNode(matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]])); node
UnknownNode (2×3)
>>> node.matrix()
[1 0 1]
[0 1 1]
>>> node = UnknownNode(matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]]),
...                    row_keys='ab',
...                    column_keys=range(Integer(3))); node
UnknownNode (2×3)
>>> node.matrix()
[1 0 1]
[0 1 1]
>>> node.morphism()._unicode_art_matrix()
  0 1 2
a⎛1 0 1⎞
b⎝0 1 1⎠

From a module morphism:

sage: phi = matrix(ZZ, [[1, 0, 1], [0, 1, 1]],
....:              row_keys='ab', column_keys=range(3)); phi
Generic morphism:
From: Free module generated by {0, 1, 2} over Integer Ring
To:   Free module generated by {'a', 'b'} over Integer Ring
sage: node = UnknownNode(phi); node
UnknownNode (2×3)
sage: node.matrix()
[1 0 1]
[0 1 1]
>>> from sage.all import *
>>> phi = matrix(ZZ, [[Integer(1), Integer(0), Integer(1)], [Integer(0), Integer(1), Integer(1)]],
...              row_keys='ab', column_keys=range(Integer(3))); phi
Generic morphism:
From: Free module generated by {0, 1, 2} over Integer Ring
To:   Free module generated by {'a', 'b'} over Integer Ring
>>> node = UnknownNode(phi); node
UnknownNode (2×3)
>>> node.matrix()
[1 0 1]
[0 1 1]
is_conetwork_matrix(decomposition=False, certificate=False, **kwds)[source]

Return whether the matrix self over \(\GF{3}\) or \(\QQ\) is a conetwork matrix. If there is some entry not in \(\{-1, 0, 1\}\), return False.

EXAMPLES:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, -1, 0], [0, 1, -1]]); node
UnknownNode (2×3)
sage: node.matrix()
[ 1 -1  0]
[ 0  1 -1]
sage: node.is_conetwork_matrix()
True
sage: result, certificate = node.is_conetwork_matrix(certificate=True)
sage: graph, forest_edges, coforest_edges = certificate
sage: graph
Digraph on 4 vertices
sage: graph.vertices(sort=True)  # the numbers have no meaning
[1, 2, 7, 12]
sage: graph.edges(sort=True, labels=False)
[(2, 1), (2, 7), (7, 1), (7, 12), (12, 1)]
sage: forest_edges    # indexed by cols of M
((2, 1), (7, 1), (7, 12))
sage: coforest_edges  # indexed by rows of M
((2, 7), (12, 1))
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), -Integer(1), Integer(0)], [Integer(0), Integer(1), -Integer(1)]]); node
UnknownNode (2×3)
>>> node.matrix()
[ 1 -1  0]
[ 0  1 -1]
>>> node.is_conetwork_matrix()
True
>>> result, certificate = node.is_conetwork_matrix(certificate=True)
>>> graph, forest_edges, coforest_edges = certificate
>>> graph
Digraph on 4 vertices
>>> graph.vertices(sort=True)  # the numbers have no meaning
[1, 2, 7, 12]
>>> graph.edges(sort=True, labels=False)
[(2, 1), (2, 7), (7, 1), (7, 12), (12, 1)]
>>> forest_edges    # indexed by cols of M
((2, 1), (7, 1), (7, 12))
>>> coforest_edges  # indexed by rows of M
((2, 7), (12, 1))
is_network_matrix(decomposition=False, certificate=False, **kwds)[source]

Return whether the matrix self over \(\GF{3}\) or \(\QQ\) is a network matrix. If there is some entry not in \(\{-1, 0, 1\}\), return False.

EXAMPLES:

sage: from sage.matrix.seymour_decomposition import UnknownNode
sage: node = UnknownNode([[1, 0], [-1, 1], [0, -1]]); node
UnknownNode (3×2)
sage: node.matrix()
[ 1  0]
[-1  1]
[ 0 -1]
sage: node.is_network_matrix()
True
sage: result, certificate = node.is_network_matrix(certificate=True)
sage: graph, forest_edges, coforest_edges = certificate
sage: graph
Digraph on 4 vertices
sage: graph.vertices(sort=True)  # the numbers have no meaning
[1, 2, 7, 12]
sage: graph.edges(sort=True, labels=False)
[(2, 1), (2, 7), (7, 1), (7, 12), (12, 1)]
sage: forest_edges    # indexed by rows of M
((2, 1), (7, 1), (7, 12))
sage: coforest_edges  # indexed by cols of M
((2, 7), (12, 1))
>>> from sage.all import *
>>> from sage.matrix.seymour_decomposition import UnknownNode
>>> node = UnknownNode([[Integer(1), Integer(0)], [-Integer(1), Integer(1)], [Integer(0), -Integer(1)]]); node
UnknownNode (3×2)
>>> node.matrix()
[ 1  0]
[-1  1]
[ 0 -1]
>>> node.is_network_matrix()
True
>>> result, certificate = node.is_network_matrix(certificate=True)
>>> graph, forest_edges, coforest_edges = certificate
>>> graph
Digraph on 4 vertices
>>> graph.vertices(sort=True)  # the numbers have no meaning
[1, 2, 7, 12]
>>> graph.edges(sort=True, labels=False)
[(2, 1), (2, 7), (7, 1), (7, 12), (12, 1)]
>>> forest_edges    # indexed by rows of M
((2, 1), (7, 1), (7, 12))
>>> coforest_edges  # indexed by cols of M
((2, 7), (12, 1))
class sage.matrix.seymour_decomposition.YSumNode[source]

Bases: SumNode

block_matrix_form()[source]

Return the block matrix constructed from the Y-sum of children.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 6, sparse=True),
....: [[1,0,1,1,0,0],[0,1,1,1,0,0],[1,0,1,0,1,1],
....: [0,-1,0,-1,1,1],[1,0,1,0,1,0],[0,-1,0,-1,0,1]])
sage: R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="y_pivot")
sage: C = certificate.child_nodes()[0]; C
YSumNode (6×6)
sage: C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
sage: C.summand_matrices()
(
[ 0  0  1  1]  [-1  1 -1 -1]
[ 1  1  1  0]  [ 0  1 -1 -1]
[ 0  1  0 -1]  [ 1  0  1  1]
[-1  0 -1  0]  [ 0  1  0 -1]
[-1  0 -1 -1], [ 1  0  0  1]
)
sage: C.row_keys()
(r0, r1, c0, r3, r4, r5)
sage: C.column_keys()
(r2, c1, c2, c3, c4, c5)
sage: C.child_keys()
(((r0, r1, c0, r3, -r2+r3), (c1, c2, c3, r2)),
 ((-c1+r0, r0, r3, r4, r5), (c1, r2, c4, c5)))
sage: C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(6), sparse=True),
... [[Integer(1),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)],
... [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)]])
>>> R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="y_pivot")
>>> C = certificate.child_nodes()[Integer(0)]; C
YSumNode (6×6)
>>> C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
>>> C.summand_matrices()
(
[ 0  0  1  1]  [-1  1 -1 -1]
[ 1  1  1  0]  [ 0  1 -1 -1]
[ 0  1  0 -1]  [ 1  0  1  1]
[-1  0 -1  0]  [ 0  1  0 -1]
[-1  0 -1 -1], [ 1  0  0  1]
)
>>> C.row_keys()
(r0, r1, c0, r3, r4, r5)
>>> C.column_keys()
(r2, c1, c2, c3, c4, c5)
>>> C.child_keys()
(((r0, r1, c0, r3, -r2+r3), (c1, c2, c3, r2)),
 ((-c1+r0, r0, r3, r4, r5), (c1, r2, c4, c5)))
>>> C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
is_concentrated_rank()[source]

Return False for the \(\Delta\)-sum node self.

concentrated_rank is named after the rank 2 and rank 0 off-diagonal blocks.

is_distributed_ranks()[source]

Return True for the \(\Delta\)-sum node self.

distributed_ranks is named after the two rank 1 off-diagonal blocks.

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12_large = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 9, 12, sparse=True),
....:                 [[ 1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1],
....:                  [ 0,  0,  0,  1, -1,  0,  0,  0,  1,  1,  1,  1],
....:                  [ 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1],
....:                  [ 1,  0,  1,  0,  0,  0,  0,  0,  1,  1,  0,  0],
....:                  [ 0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1, -1],
....:                  [ 0,  0,  0,  1,  0,  1,  0,  0,  1,  1,  0,  0],
....:                  [ 0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1, -1],
....:                  [ 0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0],
....:                  [ 0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1]])
sage: result, certificate = R12_large.is_totally_unimodular(certificate=True,
....:                                 decompose_strategy="y_pivot")
sage: C = certificate.child_nodes()[0]; C
YSumNode (9×12)
sage: C.is_distributed_ranks()
True
sage: C.is_concentrated_rank()
False
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12_large = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(9), Integer(12), sparse=True),
...                 [[ Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(1), -Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1),  Integer(1)],
...                  [ Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...                  [ Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(1),  Integer(0),  Integer(0),  Integer(0),  Integer(0), -Integer(1), -Integer(1)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0)],
...                  [ Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(0),  Integer(1),  Integer(0),  Integer(1),  Integer(0),  Integer(1)]])
>>> result, certificate = R12_large.is_totally_unimodular(certificate=True,
...                                 decompose_strategy="y_pivot")
>>> C = certificate.child_nodes()[Integer(0)]; C
YSumNode (9×12)
>>> C.is_distributed_ranks()
True
>>> C.is_concentrated_rank()
False
permuted_block_matrix()[source]

Return the permutation matrices between the matrix and the block matrix form.

OUTPUT: a tuple (Prow, BlockMatrix, Pcolumn), where self.matrix() == Prow * BlockMatrix * Pcolumn, and BlockMatrix == self.block_matrix_form().

EXAMPLES:

sage: from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
sage: R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, 6, 6, sparse=True),
....: [[1,0,1,1,0,0],[0,1,1,1,0,0],[1,0,1,0,1,1],
....: [0,-1,0,-1,1,1],[1,0,1,0,1,0],[0,-1,0,-1,0,1]])
sage: R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
sage: result, certificate = R12.is_totally_unimodular(certificate=True,
....:                           decompose_strategy="y_pivot")
sage: C = certificate.child_nodes()[0]; C
YSumNode (6×6)
sage: C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
sage: C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
sage: P_row, block_matrix, P_column = C.permuted_block_matrix()
sage: P_row^(-1) * C.matrix() * P_column^(-1) == block_matrix
True
>>> from sage.all import *
>>> from sage.matrix.matrix_cmr_sparse import Matrix_cmr_chr_sparse
>>> R12 = Matrix_cmr_chr_sparse(MatrixSpace(ZZ, Integer(6), Integer(6), sparse=True),
... [[Integer(1),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1)],
... [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],[Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(0),Integer(1)]])
>>> R12
[ 1  0  1  1  0  0]
[ 0  1  1  1  0  0]
[ 1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  1  0  1  0]
[ 0 -1  0 -1  0  1]
>>> result, certificate = R12.is_totally_unimodular(certificate=True,
...                           decompose_strategy="y_pivot")
>>> C = certificate.child_nodes()[Integer(0)]; C
YSumNode (6×6)
>>> C.matrix()
[ 1  0  0  1 -1 -1]
[ 0  1  1  1  0  0]
[-1  0  1  0  1  1]
[ 0 -1  0 -1  1  1]
[ 1  0  0  0  0 -1]
[ 0 -1  0 -1  0  1]
>>> C.block_matrix_form()
[ 0  0  1  1 -1 -1]
[ 1  1  1  0  0  0]
[ 0  1  0 -1  1  1]
[-1  0 -1  0  1  1]
[ 0  0  0  1  0 -1]
[-1  0 -1  0  0  1]
>>> P_row, block_matrix, P_column = C.permuted_block_matrix()
>>> P_row**(-Integer(1)) * C.matrix() * P_column**(-Integer(1)) == block_matrix
True