块对角矩阵

时间:2016-03-21 21:51:45

标签: r matrix symmetric

假设我有一个由许多矩阵组成的列表Z,我想从中构造一个块对角矩阵。 例如:

[[1]]
             [,1]        [,2]         [,3]
[1,] 1.002500e+00 0.001930454 1.388794e-11
[2,] 1.930454e-03 1.002500000 1.930454e-03
[3,] 1.388794e-11 0.001930454 1.002500e+00

[[2]]
             [,1]        [,2]         [,3]
[1,] 1.002500e+00 0.001930454 1.388794e-11
[2,] 1.930454e-03 1.002500000 1.930454e-03
[3,] 1.388794e-11 0.001930454 1.002500e+00

我想创建一个块对角矩阵,我目前正在使用

block = bdiag(z)

但是,当列表中的矩阵数量很大时,bdiag命令很慢。从列表中构造块对角矩阵的快速简便方法是什么?

注意我的矩阵也是对称的,列表中的每个矩阵都有相似的尺寸。

1 个答案:

答案 0 :(得分:0)

我试图做一个更快的功能,bdiag2

library(Matrix)

bdiag2 <- function(Ms){
  l <- length(Ms)
  N <- nrow(Ms[[1]])  
  i0 <- rep(1:N, times=N:1)
  s <- rep(seq(0,(l-1)*N,by=N),each=length(i0))
  i <- rep(i0,l) + s
  j0 <- 1:N -> j
  for(k in 1:N){
    j0 <- j0[-1]
    j <- c(j, j0)
  }
  j <- rep(j,l) + s
  idx <- t(upper.tri(Ms[[1]], diag = TRUE))
  x <- unlist(lapply(Ms, "[", idx))
  sparseMatrix(i, j, x = x, symmetric = TRUE)
}

# test & benchmark
N <- 5; l <- 200
Ms <- replicate(l, toeplitz(1:N), simplify = FALSE)

stopifnot(all(bdiag(Ms) == bdiag2(Ms)))

library(microbenchmark)
microbenchmark(
  bdiag = bdiag(Ms),
  bdiag2 = bdiag2(Ms)
)


> microbenchmark(
+   bdiag = bdiag(Ms),
+   bdiag2 = bdiag2(Ms)
+ )
Unit: milliseconds
   expr      min        lq      mean    median        uq       max neval cld
  bdiag 25.68078 27.393898 29.710474 28.566398 30.265242 54.393319   100   b
 bdiag2  1.34185  1.476838  1.693573  1.558724  1.769127  4.482054   100  a