使块矩阵为0

时间:2017-03-27 13:47:32

标签: r matrix

我有一个大矩阵(2160x2160),首先我想定义一个块矩阵(比如20x20)并用0s填充对角块矩阵。我正在努力实现这一目标。

例如:

From the matrix

         [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]
  [1,]    1      2     3     4     5     6     7     8     9
  [2,]    11     12    13    14    15    16    17    18    19
  [3,]    21     22    23    24    25    26    27    28    29
  [4,]    31     32    33    34    35    36    37    38    39
  [5,]    41     42    43    44    45    46    47    48    49
  [6,]    51     52    53    54    55    56    57    58    59
  [7,]    61     62    63    64    65    66    67    68    69
  [8,]    71     72    73    74    75    76    77    78    79
  [9,]    81     82    83    84    85    86    87    88    89

我首先要将块矩阵定义为3x3,然后用零填充原始矩阵的对角线块,我的示例的最终预期结果将是:

         [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]
  [1,]    0      0     0     4     5     6     7     8     9
  [2,]    0      0     0     14    15    16    17    18    19
  [3,]    0      0     0     24    25    26    27    28    29
  [4,]    31     32    33     0     0     0    37    38    39
  [5,]    41     42    43     0     0     0    47    48    49
  [6,]    51     52    53     0     0     0    57    58    59
  [7,]    61     62    63    64    65    66     0     0     0
  [8,]    71     72    73    74    75    76     0     0     0
  [9,]    81     82    83    84    85    86     0     0     0

我已经能够通过blockmatrix库的as.blockmatrix函数定义一个块矩阵。我想我应该打破子矩阵中的块,用0填充我需要的块然后重新构建我的原始矩阵,更改了对角线,但是我很难做到这一点。 任何其他实现这一目标的想法也是受欢迎的(在blockmatrix库的潜在解决方案之外)

我也看过bdiag函数,它包含了Matrix包,也包含了魔法下的adiag函数,但是没有想法。

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:4)

M成为您的矩阵,零块的大小为n x n。然后

M[(col(M) - 1) %/% n - (row(M) - 1) %/% n == 0] <- 0

给出结果,其中%/%表示整数除法。使用(col(M) - 1) %/% n - (row(M) - 1) %/% n给出一个块矩阵,其中对角线上的块仅包含零。

答案 1 :(得分:3)

您可以尝试:

m <- matrix(1:(2160*2160), ncol = 2160)
block <- 20
system.time({
    for(i in seq(1, nrow(m), block)) 
        if ((block+i-1)<=nrow(m))
            m[i:(block+i-1),i:(block+i-1)] <- 0
})
# time in seconds
user  system elapsed 
 1.17    0.89    2.10 

> m[1:25, 1:25]

      # [,1] [,2] [,3] [,4] [,5]  [,6]  [,7]  [,8]  [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25]
 # [1,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43201 45361 47521 49681 51841
 # [2,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43202 45362 47522 49682 51842
 # [3,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43203 45363 47523 49683 51843
 # [4,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43204 45364 47524 49684 51844
 # [5,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43205 45365 47525 49685 51845
 # [6,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43206 45366 47526 49686 51846
 # [7,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43207 45367 47527 49687 51847
 # [8,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43208 45368 47528 49688 51848
 # [9,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43209 45369 47529 49689 51849
# [10,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43210 45370 47530 49690 51850
# [11,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43211 45371 47531 49691 51851
# [12,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43212 45372 47532 49692 51852
# [13,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43213 45373 47533 49693 51853
# [14,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43214 45374 47534 49694 51854
# [15,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43215 45375 47535 49695 51855
# [16,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43216 45376 47536 49696 51856
# [17,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43217 45377 47537 49697 51857
# [18,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43218 45378 47538 49698 51858
# [19,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43219 45379 47539 49699 51859
# [20,]    0    0    0    0    0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0 43220 45380 47540 49700 51860
# [21,]   21 2181 4341 6501 8661 10821 12981 15141 17301 19461 21621 23781 25941 28101 30261 32421 34581 36741 38901 41061     0     0     0     0     0
# [22,]   22 2182 4342 6502 8662 10822 12982 15142 17302 19462 21622 23782 25942 28102 30262 32422 34582 36742 38902 41062     0     0     0     0     0
# [23,]   23 2183 4343 6503 8663 10823 12983 15143 17303 19463 21623 23783 25943 28103 30263 32423 34583 36743 38903 41063     0     0     0     0     0
# [24,]   24 2184 4344 6504 8664 10824 12984 15144 17304 19464 21624 23784 25944 28104 30264 32424 34584 36744 38904 41064     0     0     0     0     0
# [25,]   25 2185 4345 6505 8665 10825 12985 15145 17305 19465 21625 23785 25945 28105 30265 32425 34585 36745 38905 41065     0     0     0     0     0

答案 2 :(得分:2)

以下是使用矩阵子集的替代方法。

blockFill <- function(myMat, blockSize) {
  # get a list of the block groups
  blocks <- split(seq_len(ncol(myMat)),
                  rep(seq_len(ncol(myMat)), each=blockSize, length.out=ncol(myMat)))
  # fill in 0s with subsetting
  myMat[as.matrix(do.call(rbind, lapply(blocks, function(i) expand.grid(i, i))))] <- 0

  myMat
}

这里,split使用rep构造块的组,每个组控制块大小和长度.out以得到矩阵的正确大小。在下一行中,lapply在块组上执行expand.grid,指示要操作的矩阵的元素。这些内容与rbinddo.call合并。

举个例子,

myMat <- matrix(1:16, 4)

blockFill(myMat, 2)
     [,1] [,2] [,3] [,4]
[1,]    0    0    9   13
[2,]    0    0   10   14
[3,]    3    7    0    0
[4,]    4    8    0    0

答案 3 :(得分:2)

以下是bdiag

的另一个选项
library(Matrix)
M*!bdiag(replicate(3, matrix(1, 3, 3), simplify = FALSE))
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,]    0    0    0    4    5    6    7    8    9
# [2,]    0    0    0   14   15   16   17   18   19
# [3,]    0    0    0   24   25   26   27   28   29
# [4,]   31   32   33    0    0    0   37   38   39
# [5,]   41   42   43    0    0    0   47   48   49
# [6,]   51   52   53    0    0    0   57   58   59
# [7,]   61   62   63   64   65   66    0    0    0
# [8,]   71   72   73   74   75   76    0    0    0
# [9,]   81   82   83   84   85   86    0    0    0

数据

M <- matrix(1:100, 10, 10, byrow=TRUE)[-10, -10]