1
votes

Let's say I have a list of matrices with equal dimensions. For example:

mat = matrix(c(1,2,3,11,12,13,21,22,23), nrow = 3, ncol = 3)
mat.list = rep(list(mat), 3)
mat.list[[2]] = mat.list[[2]]*2.5
mat.list[[3]] = mat.list[[3]]*3.5

What I want is to populate a super matrix with dimensions length(mat.list)*nrow(mat) by length(mat.list)*ncol(mat) - possibly initialized as follows:

super.mat = matrix(NA, nrow = length(mat.list)*nrow(mat), ncol = length(mat.list)*ncol(mat))

according to this rule: super.mat[N*(i-1)+n,N*(j-1)+n] = mat.list[[n]][i,j]

where:

N = length(mat.list)

i and j indicate row and column indices in matrix n in mat.list

I think something in the lines of:

populateMat = function(N, n, i, j, mat, super.mat){
super.mat[N*(i-1)+n,N*(j-1)+n] = mat[i,j]
}

combined with some apply function over mat.list that executes:

outer(1:nrow(mat), 1:ncol(mat), Vectorize(function(i,j) populateMat(N,1,i,j,mat,super.mat)))

where here mat is just the a single element from mat.list, should work but obviously I need a bit of help to actually make it work.

2

2 Answers

1
votes

Once you realize it is just a re-arrangement of the block diagonal matrix, you can come up with something like this:

library(Matrix)
N <- length(mat.list)
bd <- do.call(bdiag, mat.list)
i.idx <- order(rep(seq(nrow(bd)/N), N))
j.idx <- order(rep(seq(ncol(bd)/N), N))
bd[i.idx, j.idx]
0
votes

Does the following suit your needs?:

sapply(seq_along(mat.list),
       function(x) { 
         super.mat[(seq_len(nrow(super.mat))-1)%%nrow(mat.list[[x]])+1==x,
                   (seq_len(ncol(super.mat))-1)%%ncol(mat.list[[x]])+1==x] <<- mat.list[[x]]
         return(NULL)
        })

Result:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    1   NA   NA   11   NA   NA   21   NA   NA
 [2,]   NA  2.5   NA   NA 27.5   NA   NA 52.5   NA
 [3,]   NA   NA  3.5   NA   NA 38.5   NA   NA 73.5
 [4,]    2   NA   NA   12   NA   NA   22   NA   NA
 [5,]   NA  5.0   NA   NA 30.0   NA   NA 55.0   NA
 [6,]   NA   NA  7.0   NA   NA 42.0   NA   NA 77.0
 [7,]    3   NA   NA   13   NA   NA   23   NA   NA
 [8,]   NA  7.5   NA   NA 32.5   NA   NA 57.5   NA
 [9,]   NA   NA 10.5   NA   NA 45.5   NA   NA 80.5