MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

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

  • To: mathgroup at smc.vnet.net
  • Subject: [mg113538] Re: It would be nice to have DiagonalMatrix accept a matrix as building
  • From: Daniel Lichtblau <danl at wolfram.com>
  • Date: Mon, 1 Nov 2010 05:02:50 -0500 (EST)

----- Original Message -----
> From: "Nasser M. Abbasi" <nma at 12000.org>
> To: mathgroup at smc.vnet.net
> Sent: Sunday, October 31, 2010 4:18:48 AM
> Subject: [mg113509] It would be nice to have DiagonalMatrix accept a matrix as building
> 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

Using SparseArray is probably a good way to do this. An alternative, suitable for dense matrices, uses ArrayFlatten. I'll use an auxiliary function that creates a row of zeros, with a given matrix substituted for one of the zero elements.

In[11]:= matVector[mat_, n_, pos_] := 
 ReplacePart[ConstantArray[0, n], pos -> mat]

In[17]:= diagonalBlockMatrix[mats_] := 
 ArrayFlatten[
  Table[matVector[mats[[j]], Length[mats], j], {j, Length[mats]}]]

Examples:

In[4]:= m = {{1, 2}, {3, 4}};

In[14]:= matrices = RandomInteger[{-5, 5}, {3, 2, 2}]
Out[14]= {{{1, -5}, {-4, 0}}, {{3, 4}, {-1, 2}}, {{5, -1}, {0, 2}}}

In[18]:= diagonalBlockMatrix[matrices]
Out[18]= {{1, -5, 0, 0, 0, 0}, {-4, 0, 0, 0, 0, 0}, {0, 0, 3, 4, 0, 
  0}, {0, 0, -1, 2, 0, 0}, {0, 0, 0, 0, 5, -1}, {0, 0, 0, 0, 0, 2}}

In[19]:= diagonalBlockMatrix[Table[m, {3}]]
Out[19]= {{1, 2, 0, 0, 0, 0}, {3, 4, 0, 0, 0, 0}, {0, 0, 1, 2, 0, 
  0}, {0, 0, 3, 4, 0, 0}, {0, 0, 0, 0, 1, 2}, {0, 0, 0, 0, 3, 4}}

I do not disagree that it would be nice to have DiagonalMatrix accept matrix blocks. Though there may be a compelling reason not to do so, that I fail to see at the moment.

Daniel Lichtblau
Wolfram Research



  • Prev by Date: Re: how to plot nminimized result
  • Next by Date: Re: question on passing variable to function by reference
  • Previous by thread: Re: how to plot nminimized result
  • Next by thread: can't get Mathematica 5.2 to evaluate anything