我试图在R中创建一个块循环矩阵.下面给出了一个块循环矩阵的结构.
C0 C1 ... Cn-1
Cn-1 C0 C1 ... Cn-2
Cn-2 Cn-1 .... Cn-3
and so on
Run Code Online (Sandbox Code Playgroud)
我有块
C0 .... Cn-1
Run Code Online (Sandbox Code Playgroud)
创建矩阵的最简单方法是什么?有功能吗?
感谢您提出疑问!这是一个解决方案,将矩阵的kronecker积与子对角线和超对角线相加.
样本数据,矩阵列表:
C <- lapply(1:3, matrix, nrow = 2, ncol = 2)
Run Code Online (Sandbox Code Playgroud)
我的解决方案
bcm <- function(C) {
require(Matrix)
n <- length(C)
Reduce(`+`, lapply((-n+1):(n-1),
function(i) kronecker(as.matrix(bandSparse(n, n, -i)),
C[[1 + (i %% n)]])))
}
bcm(C)
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 1 3 3 2 2
# [2,] 1 1 3 3 2 2
# [3,] 2 2 1 1 3 3
# [4,] 2 2 1 1 3 3
# [5,] 3 3 2 2 1 1
# [6,] 3 3 2 2 1 1
Run Code Online (Sandbox Code Playgroud)
我认为您正在寻找的内容是circulant.matrix从lgcp包装中找到的。
如果 x 是一个矩阵,其列是块循环矩阵的子块的基,则此函数返回感兴趣的块循环矩阵。
例如
x <- matrix(1:8,ncol=4)
circulant(x)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,] 1 2 3 4 5 6 7 8
# [2,] 2 1 4 3 6 5 8 7
# [3,] 7 8 1 2 3 4 5 6
# [4,] 8 7 2 1 4 3 6 5
# [5,] 5 6 7 8 1 2 3 4
# [6,] 6 5 8 7 2 1 4 3
# [7,] 3 4 5 6 7 8 1 2
# [8,] 4 3 6 5 8 7 2 1
Run Code Online (Sandbox Code Playgroud)
这是一种非常低效的方法,使用kronecker和Reduce
bcirc <- function(list.blocks){
P <- lapply(seq_along(list.blocks), function(x,y) x ==y, x = circulant(seq_along(list.blocks)))
Reduce('+',Map(P = P, A=list.blocks, f = function(P,A) kronecker(P,A)))
}
Run Code Online (Sandbox Code Playgroud)
与 @flodel 和 @Ben Bolker 进行基准测试
lbirary(microbenchmark)
microbenchmark(bcm(C), bcirc(C), bcMat(C))
Unit: microseconds
expr min lq median uq max neval
bcm(C) 10836.719 10925.7845 10992.8450 11141.1240 21622.927 100
bcirc(C) 444.983 455.7275 479.5790 487.0370 569.105 100
bcMat(C) 288.558 296.4350 309.8945 348.4215 2190.231 100
Run Code Online (Sandbox Code Playgroud)