I want to build a block diagonal matrix (A) from a known matrix (B) by only keeping the elements in the block diagonal from matrix (B). I would like to use R to do it.
For example, B is a 6 by 6 matrix.
B <- matrix(rnorm(36), nrow = 6)
I am looking for a function like this: function(B,3)
(3 is just a random number, it represents the total numbers of the block) which returns matrix A like this:
[1,] B11 B12 . . . .
[2,] B21 B22 . . . .
[3,] . . B33 B34 . .
[4,] . . B43 B44 . .
[5,] . . . . B55 B56
[6,] . . . . B65 B66
Really appreciate any help
CodePudding user response:
We may use bdiag
to construct a sparseMatrix
of 1s and multiply with the 'B' matrix so that values that corresponds to 0 in the sparseMatrix
becomes 0 and those corresponds to 1 remains the same
library(Matrix)
as.matrix(bdiag(rep(list(matrix(c(1, 1, 1, 1), 2, 2)), 3))) * B
-output
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] -0.8049569 -1.360807 0.0000000 0.0000000 0.000000 0.0000000
[2,] -0.2881172 1.810878 0.0000000 0.0000000 0.000000 0.0000000
[3,] 0.0000000 0.000000 -0.7705610 2.1809346 0.000000 0.0000000
[4,] 0.0000000 0.000000 0.3041445 -0.5894346 0.000000 0.0000000
[5,] 0.0000000 0.000000 0.0000000 0.0000000 2.033442 0.2190562
[6,] 0.0000000 0.000000 0.0000000 0.0000000 2.283470 -0.6036186
If we need it to be sparse, then remove the as.matrix
wrapper
> bdiag(rep(list(matrix(c(1, 1, 1, 1), 2, 2)), 3)) * B
6 x 6 sparse Matrix of class "dgCMatrix"
[1,] -0.8049569 -1.360807 . . . .
[2,] -0.2881172 1.810878 . . . .
[3,] . . -0.7705610 2.1809346 . .
[4,] . . 0.3041445 -0.5894346 . .
[5,] . . . . 2.033442 0.2190562
[6,] . . . . 2.283470 -0.6036186