【问题标题】:compute only upper triangle of matrix只计算矩阵的上三角
【发布时间】:2016-05-04 14:09:19
【问题描述】:

我有向量:

v1 = c(1,2,3)

我想从这个向量创建矩阵,其中i,j 位置上的元素将是sum i,j 位置上的向量成员:

      [,1] [,2] [,3]
 [1,]    2    3    4
 [2,]    3    4    5
 [3,]    4    5    6

问题

  1. i,jj,i 是相同的,所以没有理由计算 2x 以获得更好的性能。如何做到这一点?
  2. 如果i == j 并简单地返回NA,如何创建也不会计算元素的变体?我不是要diag(m) <- NA 命令,我要问的是如何防止计算这些元素。

PS:这是我的问题的简化版

【问题讨论】:

  • outer(v1, v1, "+")?如果这还不够快,那么 Rcpp 是您最好的选择。
  • 我认为Rcpp这本书有上三角计算作为案例研究,但我的记忆可能有误。

标签: r matrix


【解决方案1】:

有一种方法比使用 2 个嵌套循环的直接计算要快得多。它没有按照您在问题 1 中描述的术语进行优化,但它非常快,因为它是矢量化的。也许,这足以满足您的目的。 向量化(甚至矩阵)方法本身:

f1 <- function(x){
    n <- length(x)
    m <- matrix(rep(x,n),n)
    m + t(m)
}
> f1(1:3)
      [,1] [,2] [,3]
[1,]    2    3    4
[2,]    3    4    5
[3,]    4    5    6

我们还可以创建一个函数来执行基准测试。这个函数甚至比需要的还少:它只计算上三角形,但我们会看到它要慢得多。

f2 <- function(x){
    n <- length(x)
    m <- matrix(rep(NA,n^2),n)
    for(i in 1:(n-1)){
        for(j in (i+1):n) m[i,j] <- x[[i]] + x[[j]]
    }
    m
}
> f2(1:3)
      [,1] [,2] [,3]
[1,]   NA    3    4
[2,]   NA   NA    5
[3,]   NA   NA   NA

基准测试:

library(microbenchmark)    
> microbenchmark(f1(1:100), f2(1:100))
Unit: microseconds
      expr       min         lq       mean    median        uq       max neval
 f1(1:100)   124.775   138.6175   181.6401   187.731   196.454   294.301   100
 f2(1:100) 10227.337 10465.1285 11000.1493 10616.830 10907.148 15826.259   100

【讨论】:

  • 这远没有outer()函数快。像这样的方法也更慢m[lower.tri(m)] &lt;- m[upper.tri(m)] &lt;- colSums(combn(a, 2)); diag(m) &lt;- a+a
猜你喜欢
  • 2016-06-09
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
相关资源
最近更新 更多