For example, like this:
I know Join
works, but it is a bit troublesome for multiple matrices. I also tried DiagonalMatrix
, but it can only form a matrix from a list of elements.
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityybeltukov's blockArray
from Speeding up generation of block diagonal matrix blows the methods below out of the water by orders of magnitude, in terms of performance.
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
b = {{1, 2}, {3, 4}};
ArrayFlatten[{{a, 0}, {0, b}}] // MatrixForm
You can Fold
this operation over a list of matrices to get a diagonal:
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
b = {{1, 2}, {3, 4}};
c = {{1, 2, 3}, {4, 5, 6}};
d = {{1, 2}, {3, 4}, {5, 6}};
Fold[ArrayFlatten[{{#, 0}, {0, #2}}] &, a, {b, c, d}] // MatrixForm
Here is another way to do this, illustrating a forcing of DiagonalMatrix
by using an arbitrary head (Hold
) on top of List
:
DiagonalMatrix[Hold /@ {a, b, c, d}] // ReleaseHold // ArrayFlatten // MatrixForm
(same output)
Or a bit more cleanly using Unevaluated
(though this may be harder to apply in a program as opposed to interactive input because the elements of your matrix list will probably not be named):
DiagonalMatrix[Unevaluated @ {a, b, c, d}] // ArrayFlatten // MatrixForm
(same output)
Diagonal
needs to "see" a simple vector (list) of elements (i.e. not matrices themselves) for it to work in the manner I need here. Unevaluated @ {a, b, c, d}
works because {a, b, c, d}
is expressly a vector of elements, and Unevaluated
keeps the evaluator from changing it before Diagonal
"sees" it. However Table[. . .]
is not expressly a vector and therefore Diagonal
doesn't know how to operate on it. This is what I meant by "may be harder to apply in a program." (continued)
$\endgroup$
Apr 17, 2017 at 16:26
Update: Just bumped into this: SparseArray`SparseBlockMatrix
:
bmF = With[{r = MapIndexed[#2[[1]] {1, 1}-># &, #, 1]}, SparseArray`SparseBlockMatrix[r]]&;
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
b = {{1, 2}, {3, 4}};
c = {{x, y, z}, {u, v, w}};
bmF[{a, b, c}] // MatrixForm
Original post:
diagF = With[{dims = Total@(Dimensions /@ {##})},
SparseArray[Band[{1, 1}, dims] -> {##}, dims]] &;
Edit: Much more elegant form (thanks to Mr.Wizard)
diagF = SparseArray[Band[{1, 1}] -> {##}] &
Example:
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
b = {{1, 2}, {3, 4}};
c = {{1, 2, 3}, {4, 5, 6}};
d = {{1, 2}, {3, 4}, {5, 6}};
diagF[a, b, d, b, c] // MatrixForm
diagF = SparseArray[Band[{1, 1}] -> {##}] &
$\endgroup$
Feb 18, 2013 at 10:21
ClearAll
more often.)
$\endgroup$
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
b = {{1, 2}, {3, 4}}; SparseArray[Band[{1, 1}] -> {a, b}] // MatrixForm
ArrayFlatten
. $\endgroup$