R: Is there a simple and efficient way to get back the list of building block matrices of a block-diagonal matrix?

前提是你 提交于 2020-01-01 15:08:29

问题


I'm looking for a (build-in) function, which efficiently returns the list of building blocks of a block-diagonal matrix in the following way (rather than iterating over the slots to get the list manually):

#construct bdiag-matrix
library("Matrix")
listElems <- list(matrix(1:4,ncol=2,nrow=2),matrix(5:8,ncol=2,nrow=2))
mat <- bdiag(listElems)

#get back the list
res <- theFunctionImLookingFor(mat)

The result res yields the building blocks:

[[1]]
      [,1] [,2]
[1,]    1    3
[2,]    2    4

[[2]]
      [,1] [,2]
[1,]    5    7
[2,]    6    8

Edit: Regarding my use case, the list elements in listElems are square and symmetric matrices. If the block is a diagonal matrix, theFunctionImLookingFor should return a list element for each diagonal element.

However, the function should be able to deal with building block matrices like

       [,1] [,2] [,3]
[1,]    1    1    0
[2,]    1    1    1
[3,]    0    1    1

or

       [,1] [,2] [,3]
[1,]    1    0    1
[2,]    0    1    1
[3,]    1    1    1

i.e. deal with zeros in blocks, which are not diagonal matrices.


回答1:


I hope this will work for all your cases, the test at the bottom includes a block that contains zeroes.

theFunctionImLookingFor <- function(mat, plot.graph = FALSE) {
   stopifnot(nrow(mat) == ncol(mat))
   x <- mat
   diag(x) <- 1
   edges <- as.matrix(summary(x)[c("i", "j")])
   library(igraph)
   g <- graph.edgelist(edges, directed = FALSE)
   if (plot.graph) plot(g)
   groups <- unique(Map(sort, neighborhood(g, nrow(mat))))
   sub.Mat <- Map(`[`, list(mat), groups, groups, drop = FALSE)
   sub.mat <- Map(as.matrix, sub.Mat)
   return(sub.mat)
}

listElems <- list(matrix(1:4,ncol=2,nrow=2),
                  matrix(5:8,ncol=2,nrow=2),
                  matrix(c(0, 1, 0, 0, 0, 1, 0, 0, 1),ncol=3,nrow=3),
                  matrix(1:1,ncol=1, nrow=1))

mat <- bdiag(listElems)

theFunctionImLookingFor(mat, plot.graph = TRUE)
# [[1]]
#      [,1] [,2]
# [1,]    1    3
# [2,]    2    4

# [[2]]
#      [,1] [,2]
# [1,]    5    7
# [2,]    6    8

# [[3]]
#      [,1] [,2] [,3]
# [1,]    0    0    0
# [2,]    1    0    0
# [3,]    0    1    1

# [[4]]
#      [,1]
# [1,]    1



来源:https://stackoverflow.com/questions/26773290/r-is-there-a-simple-and-efficient-way-to-get-back-the-list-of-building-block-ma

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!