Wakan Tanka
Wakan Tanka

Reputation: 8042

compute only upper triangle of matrix

I have vector:

v1 = c(1,2,3)

From this vector I want to create matrix where element on i,j position will be sum of vector members on i,j positions:

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

Questions:

  1. i,j and j,i is the same, so there is no reason to compute it 2x for better performance. How to achieve this?
  2. How to create also variant which will not compute elements if i == j and simply returns NA instead? I'm not asking for diag(m) <- NA command, I'm asking how to prevent computing those elements.

PS: This is reduced version of my problem

Upvotes: 2

Views: 1186

Answers (1)

Iaroslav Domin
Iaroslav Domin

Reputation: 2718

There is an approach that is much faster than a straightforward calculation with 2 nested loops. It's not optimized in terms that you described in the question 1, but it's pretty fast because it's vectorized. Maybe, it will be enough for your purpose. Vectorized (or even matrix) approach itself:

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

We can also create a function for straightforward approach to perform benchmark. This function does even less than needed: it calculates only upper triangle, but we will see that it's much slower.

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

Benchmark:

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

Upvotes: 1

Related Questions