and*_*and 10 r matrix vectorization
我想将大小的矩阵分成大小的k x l块,n x n考虑到一个问题o(就像Mathematica的分区函数那样).
例如,给定矩阵之A类的
A <- matrix(seq(1:16), nrow = 4, ncol = 4)
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
Run Code Online (Sandbox Code Playgroud)
和块大小= 3,偏移= 1,我想要输出我得到的四个子矩阵
A[1:3, 1:3]
A[1:3, 2:4]
A[2:4, 1:3]
A[2:4, 2:4]
Run Code Online (Sandbox Code Playgroud)
如果offset等于2或3,则此示例的输出应该只是我得到的子矩阵
A[1:3, 1:3]
Run Code Online (Sandbox Code Playgroud)
我该如何对此进行矢量化?
可能有更优雅的方式。myPartition以下是我通过编写一个模拟 mathematica 函数的函数来实现的方法Partition。首先使用 use沿我们要考虑的Map行和列轴构建可能的索引,然后使用from构建子集索引的所有可能组合的列表。最后用于对矩阵进行子集化并返回子集矩阵列表;seqoffsetcross2purrrlapply
offset和的测试结果如下1,似乎表现符合预期:23
library(purrr)
ind <- function(k, n, o) Map(`:`, seq(1, k-n+1, by = o), seq(n, k, by = o))
# this is a little helper function that generates subset index according to dimension of the
# matrix, the first sequence construct the starting point of the subset index with an interval
# of o which is the offset while the second sequence construct the ending point of the subset index
# use Map to construct vector from start to end which in OP's case will be 1:3 and 2:4.
myPartition <- function(mat, n, o) {
lapply(cross2(ind(nrow(mat),n,o), ind(ncol(mat),n,o)), function(i) mat[i[[1]], i[[2]]])
}
# This is basically an lapply. we use cross2 to construct combinations of all subset index
# which will be 1:3 and 1:3, 1:3 and 2:4, 2:4 and 1:3 and 2:4 and 2:4 in OP's case. Use lapply
# to loop through the index and subset.
# Testing case for offset = 1
myPartition(A, 3, 1)
# [[1]]
# [,1] [,2] [,3]
# [1,] 1 5 9
# [2,] 2 6 10
# [3,] 3 7 11
# [[2]]
# [,1] [,2] [,3]
# [1,] 2 6 10
# [2,] 3 7 11
# [3,] 4 8 12
# [[3]]
# [,1] [,2] [,3]
# [1,] 5 9 13
# [2,] 6 10 14
# [3,] 7 11 15
# [[4]]
# [,1] [,2] [,3]
# [1,] 6 10 14
# [2,] 7 11 15
# [3,] 8 12 16
# Testing case for offset = 2
myPartition(A, 3, 2)
# [[1]]
# [,1] [,2] [,3]
# [1,] 1 5 9
# [2,] 2 6 10
# [3,] 3 7 11
# Testing case for offset = 3
myPartition(A, 3, 3)
# [[1]]
# [,1] [,2] [,3]
# [1,] 1 5 9
# [2,] 2 6 10
# [3,] 3 7 11
Run Code Online (Sandbox Code Playgroud)