Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This question already has an answer here:

like this: enter image description here

I know join[...] works, but it is a bit troublesome for multiple matrices.I tried DiagonalMatrix[...], but DiagonalMatrix can only form matrix from a list of elements.

share|improve this question
3  
Have a look at ArrayFlatten. – b.gatessucks Feb 18 at 9:17

marked as duplicate by rm -rf Feb 18 at 19:32

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2 Answers

up vote 10 down vote accepted
 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

enter image description here

share|improve this answer
1  
I forgot about that. Nice. – Mr.Wizard Feb 18 at 10:16
If I am not mistaken this function can be reduced to: diagF = SparseArray[Band[{1, 1}] -> {##}] & – Mr.Wizard Feb 18 at 10:21
@Mr.Wizard, you are right! (somehow I did not get that form working when I first tried; need to use ClearAll more often.) – kguler Feb 18 at 10:31
1  
+1 Great solution. It may be worth pointing out, though, that the example is not a block-diagonal matrix. By definition, a block-diagonal matrix represents an endomorphism of a product of vector spaces in which each component space is mapped to itself; ergo, the blocks must be square. But it is evident that this solution will work correctly when its input matrices are all square; it can be thought of as a generalization of the block-diagonal form in which the matrix represents a Cartesian product of arbitrary linear maps (rather than just endomorphisms). – whuber Feb 18 at 18:10
@whuber, thanks. Great observation. – kguler Feb 18 at 18:32
show 10 more comments
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

b = {{1, 2}, {3, 4}};

ArrayFlatten[{{a, 0}, {0, b}}] // MatrixForm

Mathematica graphics

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

Mathematica graphics

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)

share|improve this answer
Mr.Wizard What about a list of Matrices? I only examplified two matrices to form one block-diagonal matrix. Better automatic method. – novice Feb 18 at 9:31
@user5463 what do you mean? – Mr.Wizard Feb 18 at 9:31
Suppose my matrices are not predefined, but generated in the middle of my program. – novice Feb 18 at 9:37
@user5463 see my updated answer; is that what you want? – Mr.Wizard Feb 18 at 9:43
Thanks, it is neat. – novice Feb 18 at 9:45
show 4 more comments

Not the answer you're looking for? Browse other questions tagged or ask your own question.