在 r 中创建不等维的对角矩阵

mon*_*nic 4 r matrix

有没有diag()类似的方法在 r 中创建不等维对角矩阵?例如:

> diag(rep(1,9), nrow=3)
 
1 1 1 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 1 1 1
Run Code Online (Sandbox Code Playgroud)

Tho*_*ing 9

尝试克罗内克产品

> kronecker(diag(1, 3), t(rep(1, 3)))
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    1    1    0    0    0    0    0    0
[2,]    0    0    0    1    1    1    0    0    0
[3,]    0    0    0    0    0    0    1    1    1
Run Code Online (Sandbox Code Playgroud)

或更短且等效的形式%x%

> diag(1, 3) %x% t(rep(1, 3))
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    1    1    0    0    0    0    0    0
[2,]    0    0    0    1    1    1    0    0    0
[3,]    0    0    0    0    0    0    1    1    1
Run Code Online (Sandbox Code Playgroud)

其他选项可能使用tcrossprod+rep

> n <- 3

> +(tcrossprod(rep(1, n), rep(1:n, each = n)) == 1:n)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    1    1    0    0    0    0    0    0
[2,]    0    0    0    1    1    1    0    0    0
[3,]    0    0    0    0    0    0    1    1    1
Run Code Online (Sandbox Code Playgroud)

outer+==

> n <- 3

> +outer(1:n, rep(1:n, each = n), `==`)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    1    1    0    0    0    0    0    0
[2,]    0    0    0    1    1    1    0    0    0
[3,]    0    0    0    0    0    0    1    1    1
Run Code Online (Sandbox Code Playgroud)

标杆管理

f0 <- function(n) {
    diag(1, n) %x% t(rep(1, n))
}

f1 <- function(n) {
    +(tcrossprod(rep(1, n), rep(1:n, each = n)) == 1:n)
}

f2 <- function(n) {
    +outer(1:n, rep(1:n, each = n), `==`)
}


bm <- function(n) {
    microbenchmark(
        kron = f0(n),
        tprep = f1(n),
        outer = f2(n),
        check = "equivalent",
        unit = "relative"
    )
}
Run Code Online (Sandbox Code Playgroud)

节目

> bm(3)
Unit: relative
  expr       min       lq      mean    median        uq       max neval
  kron 11.895263 11.04810 1.7791532 10.679845 10.037901 0.8851459   100
 tprep  1.000000  1.00000 1.0000000  1.000000  1.000000 1.0000000   100
 outer  2.421579  2.38119 0.9050314  2.363099  2.249479 0.7652963   100

> bm(10)
Unit: relative
  expr      min       lq     mean   median       uq      max neval
  kron 5.306864 5.097848 4.241431 4.915007 4.810881 4.291035   100
 tprep 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000   100
 outer 2.076524 2.017677 1.719520 1.966105 1.929139 1.177178   100

> bm(100)
Unit: relative
  expr      min       lq     mean   median       uq       max neval
  kron 1.194080 1.267156 1.072417 1.318485 1.068942 0.2659374   100
 tprep 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000   100
 outer 1.583671 1.582495 1.387049 1.445595 1.288268 1.0790626   100
Run Code Online (Sandbox Code Playgroud)