# Creating a block diagonal matrix when the submatrices in the diagonal are unknown

Let us assume that we have an integer $$j$$ $$(j=1,2,...,k)$$ and that for every $$j$$ is generated a matrix $$P$$ of dimensions $$j$$x$$j$$ . For example, if $$j=1$$ then $$P=(-2)$$.

If $$j=2$$ then

$$R = \begin{pmatrix} -2 & 1 \\ 0 & -2 \end{pmatrix}$$

If $$j=3$$ then

$$R = \begin{pmatrix} -2 & 1 &0 \\ 0 & -2 & 1 \\ 0 & 0 & -2 \end{pmatrix}$$ and so forth.

I want to construct a block diagonal matrix $$J$$ with all the matrices $$P$$ (which have been generated before, in the iteration of $$j$$) in the diagonal elements. I suppose that ArrayFlatten and DiagonalMatrix should be used but I don't know in what way. Any help appreciated, thank you.

Like this?

Clear["*"];
jordan[j_ /; j >= 2] :=
SparseArray[{Band[{1, 1}] -> -2, Band[{1, 2}] -> 1}, {j, j}]
jordan[j_ /; j == 1] := {{-2}};
n = 5;
SparseArray[{Band[{1, 1}] -> Table[jordan[j] // Normal, {j, 1, n}]},
Sum[j, {j, 1, n}]]
% // MatrixForm

• Oh yes this is really helpful to me.You understood exactly what I meant!
– arod
Oct 23, 2020 at 9:27
• One more question. If I don't have -2 in every matrix but for j=1 I have {{-1}}, for j=2 I have {{1,1},{0,1}}, for j=3 {{-2,1,0},{0,-2,1},{0,0,-2}},... (every matrix is different) then what should I do ?
– arod
Oct 23, 2020 at 10:15
• @arod R1 = {{-2}}; R2 = {{1, 1}, {0, 1}}; R3 = {{-2, 1, 0}, {0, -2, 1}, {0, 0, -2}}; SparseArray[{Band[{1, 1}] -> Normal /@ {R1, R2, R3}}]; % // Normal // MatrixForm Oct 23, 2020 at 11:10
• The matrices I mentioned are random. I do not know the matrices in each iteration of j. How can what you said be done in a more general case?
– arod
Oct 23, 2020 at 11:16
SparseArray[Band[{1, 1}] -> (P /@ Range[n])]


If P produces SparseArrays, this does not seem to work. Then one can either convert to dense arrays with Normal like this

SparseArray[Band[{1, 1}] -> (Normal@*P /@ Range[n])]


or one can emply the undocumented function SparseArraySparseBlockMatrix as follows:

SparseArraySparseBlockMatrix[{#, #} -> P[#] & /@ Range[5]]

• I'm not sure if this turns out the result I want.
– arod
Oct 23, 2020 at 9:27
• You did not tell us that P produces SparseArrays. Apparently, one has to convert to dense arrays with Normal, first. Oct 23, 2020 at 9:47

"I suppose that ArrayFlatten and DiagonalMatrix should be used but I don't know in what way."

Other answers show that ArrayFlatten or DiagonalMatrix are not needed. But, in case you wish to use them, here is a way:

P[n_] /; n > 1 := -2 IdentityMatrix[n] +
DiagonalMatrix[ConstantArray[1, n - 1], 1];
P[1] = {{-2}};

n = 5;

MatrixForm @
ArrayFlatten[DiagonalMatrix[Range @ n] /. i_Integer?Positive :> P @ i]


You can also use ArrayFlatten + IdentityMatrix:

plist = P /@ Range[n];

MatrixForm @
ArrayFlatten[IdentityMatrix[n] /. 1 :> Last[plist = RotateLeft[plist]]]

 same picture


Both methods work with arbitrary list of matrices,

Q[{n_, m_}] := Array[Subscript[x, Row @ {##}] &, {n, m}];

SeedRandom[1]
qlist = Table[Q @ RandomInteger[{2, 6}, 2], n];

MatrixForm @
ArrayFlatten[DiagonalMatrix[Range @ n] /. i_Integer?Positive :> qlist[[i]]]


MatrixForm @
ArrayFlatten[IdentityMatrix[n] /. 1 :> Last[qlist = RotateLeft[qlist]]]

 same picture

• No it was not necessary for me to use ArrayFlatten and DiagonalMatrix but I thought these commands should be used - I didn't know about Band. Anyway, thank you, your method works fine!
– arod
Oct 24, 2020 at 15:06
Table[Which[x + 1 == y, 1, x == y, -2, True, 0], {x, 0, #}, {y, 0, #}] &@5
`

{{-2, 1, 0, 0, 0, 0}, {0, -2, 1, 0, 0, 0}, {0, 0, -2, 1, 0, 0}, {0, 0, 0, -2, 1, 0}, {0, 0, 0, 0, -2, 1}, {0, 0, 0, 0, 0, -2}}