Determine if Matrix can be permutated into Block Diagonal Matrix
Problem
Given an $n\times n$ matrix $A=(a_{ij})$, determine if it is possible to find a permutation matrix $P=(p_{ij})$ and square matrices $B$ and $C$ such that $$ PAP^{\intercal}=\begin{pmatrix}B & 0\\ 0 & C \end{pmatrix}. $$
Note: By grouping blocks, any matrix with three or more diagonal blocks can also be considered as a matrix with two diagonal blocks. For example,
$$ \begin{pmatrix}B\\ & C\\ & & D \end{pmatrix}=\begin{pmatrix}B\\ & \begin{pmatrix}C\\ & D \end{pmatrix} \end{pmatrix} $$
Solution
Let $G=(V,E)$ denote the undirected adjacency graph of $A$. That is, $V$ and $E$ are defined by $$ V=\{1,\ldots,n\}\qquad\text{and}\qquad E=\left\{ (i,j)\in V\times V\colon a_{ij}\neq0\text{ or }a_{ji}\neq0\right\}. $$ Now, our original problem is equivalent to determining whether $G$ is a graph with two or more disjoint components.
This is accomplished with a breadth-first search (or depth-first search) started at an arbitrary vertex, call it $v_{1}$. Let $V^{\prime}=\{v_{1},\ldots,v_{k}\}$ be the set of vertices visited by the search. Then, the answer to our original problem is in the affirmitive if and only if $V^{\prime}$ is a proper subset of $V$.
Example
Let's apply the algorithm to the matrix $$ A=\begin{pmatrix}0 & 0 & 7 & 0 & 0\\ 0 & 0 & 0 & 0 & 3\\ 5 & 0 & 0 & 1 & 0\\ 0 & 0 & 2 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 \end{pmatrix}. $$
Let's run the search algorithm:
- Pick $v_{1}=1$ corresponding to the first row.
- The only nonzero entry in this row is $a_{v_{1}3} = 7$ so we pick $v_{2}=3$ as the next row to visit.
- The only nonzero entries in this row are $a_{v_{2}1} = 5$ and $a_{v_{2}4} = 1$. We have already visited the first row so we pick $v_{3}=4$ as the next row to visit.
- The only nonzero entry in this row is $a_{v_{3} 3} = 2$. We have already visited the third row and hence the search terminates.
The final vertex set is $V^{\prime}=\{v_1,v_2,v_3\}=\{1,3,4\}$. Next, make any permutation matrix that satisfies $p_{1v_{1}}=p_{2v_{2}}=p_{3v_{3}}=1$. For example, we could take $$ P=\begin{pmatrix}1 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 1 & 0\\ 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 1 \end{pmatrix}. $$ You can check that $PAP^{\intercal}$ has two diagonal blocks: $$ PAP^{\intercal}=\begin{pmatrix}0 & 7 & 0 & 0 & 0\\ 5 & 0 & 1 & 0 & 0\\ 0 & 2 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 3\\ 0 & 0 & 0 & 1 & 0 \end{pmatrix}. $$
MATLAB implementation
The code below can be used to make the matrix P
described above from an input matrix A
. Just call perm_mat_to_make_block_diag(A)
.
Note: I don't have access to MATLAB and GNU Octave has not implemented the breadth-first search function bfsearch
, so I was unable to test the code below. If someone could test it for me, that would be great.
function P = perm_mat_to_make_block_diag(A)
% Make the undirected adjacency graph for A.
nonzero = A != 0;
adjacency = nonzero + nonzero';
G = graph(A);
% Perform breadth-first search.
v_1 = 1;
V_prime = bfsearch(G, v_1);
n = length(A);
if length(V_prime) == n
error('Input is not permutation-similar to a block-diagonal matrix.');
end
% Make the permutation matrix.
i = (1:n)';
V_prime_complement = setdiff(i, V_prime);
j = [V_prime; V_prime_complement];
P = sparse(i, j, ones(n, 1), n, n);
end