Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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
5  
Have a look at ArrayFlatten. –  b.gatessucks Feb 18 '13 at 9:17
    
Thanks for the Accept. –  Mr.Wizard Jan 3 at 8:50
add comment

2 Answers 2

up vote 20 down vote accepted
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 '13 at 9:31
    
@user5463 what do you mean? –  Mr.Wizard Feb 18 '13 at 9:31
    
Suppose my matrices are not predefined, but generated in the middle of my program. –  novice Feb 18 '13 at 9:37
    
@user5463 see my updated answer; is that what you want? –  Mr.Wizard Feb 18 '13 at 9:43
    
Thanks, it is neat. –  novice Feb 18 '13 at 9:45
show 4 more comments
 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 '13 at 10:16
    
If I am not mistaken this function can be reduced to: diagF = SparseArray[Band[{1, 1}] -> {##}] & –  Mr.Wizard Feb 18 '13 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 '13 at 10:31
2  
+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 '13 at 18:10
    
@whuber, thanks. Great observation. –  kguler Feb 18 '13 at 18:32
show 11 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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