Re: It would be nice to have DiagonalMatrix accept a matrix as building

*To*: mathgroup at smc.vnet.net*Subject*: [mg113512] Re: It would be nice to have DiagonalMatrix accept a matrix as building*From*: Zach Bjornson <bjornson at stanford.edu>*Date*: Sun, 31 Oct 2010 05:22:01 -0500 (EST)*References*: <iajcai$p6j$1@smc.vnet.net>

(this is probably better submitted to Wolfram as a feature request, they're very responsive) You can use Band to avoid looping constructs: DiagonalM[block_, nBlocks_] := Normal@ SparseArray[Band[{1, 1}] -> ConstantArray[block, {nBlocks}]] I thought there was a still shorter version, but can't recall it... Best, Zach On 10/31/2010 2:19 AM, Nasser M. Abbasi wrote: > Sometime there is a need to make a matrix with repeating subblocks on > the diagonal. For example, one might want to create matrix A, with > matrix B on its diagonal, repeated n times. > > DiagonalMatrix only accepts vector (list), not matrix (list of lists), > as its argument. > > So, one has the option to use DiagonalMatrix, repeatedly, using > different offsets at a time, and manually layout the diagonal. Or use > SparseArray since SparseArray accepts a matrix as the band, but also > make a loop to add the block at different locations on the diagonal. > > The SparseArray method is little less work, but I think a nice solution > would be to have the ability to specify the block, and how many time it > needs to be repeated on the diagonal. That other 'system' has this > command to do that. > > This is how I now create a diagonalMatrix with matrices at its diagonal. > Maybe an expert here knows of a short way or trick to use. > > In this example, I wanted to make matrix 'a' with the submatrix > > {{1,2}{3,4}} > > on its diagonal, and wanted this repeated 6 times. So, I made a large > cup of coffee, sat down and wrote this > > ---------------------------- > block={{1,2},{3,4}}; > sizeOfBlock=Length[block]; > nBlocks=6; > a=Table[0,{i,sizeOfBlock*nBlocks},{j,sizeOfBlock*nBlocks}]; > Do[ > a=a+Normal@SparseArray[Band[{i*sizeOfBlock+1,i*sizeOfBlock+1}]->block,nBlocks*sizeOfBlock], > {i,0,nBlocks-1} > ]; > -------------------------- > > {{1,2,0,0,0,0,0,0,0,0,0,0},{3,4,0,0,0,0,0,0,0,0,0,0}, > {0,0,1,2,0,0,0,0,0,0,0,0},{0,0,3,4,0,0,0,0,0,0,0,0}, > {0,0,0,0,1,2,0,0,0,0,0,0},{0,0,0,0,3,4,0,0,0,0,0,0}, > {0,0,0,0,0,0,1,2,0,0,0,0},{0,0,0,0,0,0,3,4,0,0,0,0}, > {0,0,0,0,0,0,0,0,1,2,0,0},{0,0,0,0,0,0,0,0,3,4,0,0}, > {0,0,0,0,0,0,0,0,0,0,1,2},{0,0,0,0,0,0,0,0,0,0,3,4}} > > So, it works. > > But if what I had imagined existed, I should have been able to do > > DiagonalMatrix[block,0,6] > > Again, the above command would only work if 'block' was a 1-D list, not > a 2-D list (ie. a matrix). > > of course, I can make a function and hide the code I wrote inside this > function, and it would just look the same as the call that I wanted. > > All what I am saying is that Mathematica should support this feature as > part of DiagonalMatrix as it is very common thing. > > thanks > --Nasser