Repeating the block matrix many times in the diagonal part of the block matrix, with off-diagonal blocks all null matrices?

I would like to create a block-diagonal matrix where the diagonal blocks are repeated a certain number of times, with the off-diagonal blocks being all null matrices. For example, suppose we start with a matrix with the following:

> diag.matrix

       [,1] [,2] [,3] [,4] [,5]
  [1,]  1.0  0.5  0.5  0.5  0.5
  [2,]  0.5  1.0  0.5  0.5  0.5
  [3,]  0.5  0.5  1.0  0.5  0.5
  [4,]  0.5  0.5  0.5  1.0  0.5
  [5,]  0.5  0.5  0.5  0.5  1.0

      

I would like this matrix to be a diagonal block matrix, so I end up with something like:

       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]  1.0  0.5  0.5  0.5  0.5  0.0  0.0  0.0  0.0   0.0
 [2,]  0.5  1.0  0.5  0.5  0.5  0.0  0.0  0.0  0.0   0.0
 [3,]  0.5  0.5  1.0  0.5  0.5  0.0  0.0  0.0  0.0   0.0
 [4,]  0.5  0.5  0.5  1.0  0.5  0.0  0.0  0.0  0.0   0.0
 [5,]  0.5  0.5  0.5  0.5  1.0  0.0  0.0  0.0  0.0   0.0
 [6,]  0.0  0.0  0.0  0.0  0.0  1.0  0.5  0.5  0.5   0.5
 [7,]  0.0  0.0  0.0  0.0  0.0  0.5  1.0  0.5  0.5   0.5
 [8,]  0.0  0.0  0.0  0.0  0.0  0.5  0.5  1.0  0.5   0.5
 [9,]  0.0  0.0  0.0  0.0  0.0  0.5  0.5  0.5  1.0   0.5
[10,]  0.0  0.0  0.0  0.0  0.0  0.5  0.5  0.5  0.5   1.0

      

Here we have the same block matrix repeated twice in block diagonals. If I wanted to do this efficiently and arbitrarily, is there a way to do it? thank!

+3


source to share


1 answer


1) kronecker If M

is your matrix and k

is the number of times you want to iterate, then:

kronecker(diag(k), M)

      

For example,

M <- matrix(0.5, 5, 5) + diag(0.5, 5)
k <- 2
kronecker(diag(k), M)

      

giving:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]  1.0  0.5  0.5  0.5  0.5  0.0  0.0  0.0  0.0   0.0
 [2,]  0.5  1.0  0.5  0.5  0.5  0.0  0.0  0.0  0.0   0.0
 [3,]  0.5  0.5  1.0  0.5  0.5  0.0  0.0  0.0  0.0   0.0
 [4,]  0.5  0.5  0.5  1.0  0.5  0.0  0.0  0.0  0.0   0.0
 [5,]  0.5  0.5  0.5  0.5  1.0  0.0  0.0  0.0  0.0   0.0
 [6,]  0.0  0.0  0.0  0.0  0.0  1.0  0.5  0.5  0.5   0.5
 [7,]  0.0  0.0  0.0  0.0  0.0  0.5  1.0  0.5  0.5   0.5
 [8,]  0.0  0.0  0.0  0.0  0.0  0.5  0.5  1.0  0.5   0.5
 [9,]  0.0  0.0  0.0  0.0  0.0  0.5  0.5  0.5  1.0   0.5
[10,]  0.0  0.0  0.0  0.0  0.0  0.5  0.5  0.5  0.5   1.0

      

1a)% x% The last line of code can be written as:



diag(k) %x% M

      

2) Matrix :: bdiag Another possibility if you want to save space is to create a sparse matrix of the class "dgMCatrix"

. It does not store null values. See ?bdiag

:

library(Matrix)

bdiag(replicate(k, M, simplify = FALSE))

      

giving:

10 x 10 sparse Matrix of class "dgCMatrix"

 [1,] 1.0 0.5 0.5 0.5 0.5 .   .   .   .   .  
 [2,] 0.5 1.0 0.5 0.5 0.5 .   .   .   .   .  
 [3,] 0.5 0.5 1.0 0.5 0.5 .   .   .   .   .  
 [4,] 0.5 0.5 0.5 1.0 0.5 .   .   .   .   .  
 [5,] 0.5 0.5 0.5 0.5 1.0 .   .   .   .   .  
 [6,] .   .   .   .   .   1.0 0.5 0.5 0.5 0.5
 [7,] .   .   .   .   .   0.5 1.0 0.5 0.5 0.5
 [8,] .   .   .   .   .   0.5 0.5 1.0 0.5 0.5
 [9,] .   .   .   .   .   0.5 0.5 0.5 1.0 0.5
[10,] .   .   .   .   .   0.5 0.5 0.5 0.5 1.0

      

2b) Diagonal or create a sparse class matrix "dgTMatrix"

:

Diagonal(k) %x% M

      

+8


source







All Articles