Camford Oxbridge
Camford Oxbridge

Reputation: 894

Vectorization from different dimensional arrays in R

for(i in 1:1111){
for(j in 1:2222){
for(k in 1:3333){

      y[i, j, k] <- a[i] + b[j, k] 
}
}
}

where a[ ], b[, ], y[ , , ] is arrays.

This code take a long time, so I want to vectorization or any treatment to be more faster code.

Someone have any idea to make the code faster.

One way to solve, I am not sure, but by adjusting the index by replicating the arrays, it goes well ?

see for replication:

Replicating 2 dimensional matrix to create a 3 dimensional array (in R)

I am not sure array format make code faster.

If dimensions of arrays a,b,y have same, then the code will simplify by

y <-a+b

and this seems faster code.

Upvotes: 3

Views: 114

Answers (1)

Rui Barradas
Rui Barradas

Reputation: 76460

The solution is simpler than what it seems. Just get rid of the two inner loops.
I have written the solution in the form of function for tests sake.

f1 <- function(m, n, o){
  a <- seq_len(m)
  b <- matrix(1:(n*o), nrow = n)
  y <- array(0, dim = c(m, n, o))
  for(i in seq_len(m)){
    for(j in seq_len(n)){
      for(k in seq_len(o)){
        y[i, j, k] <- a[i] + b[j, k] 
      }
    }
  }
  y
}

f2 <- function(m, n, o){
  a <- seq_len(m)
  b <- matrix(1:(n*o), nrow = n)
  y <- array(0, dim = c(m, n, o))
  for(i in seq_len(m)){
    y[i, , ] <- a[i] + b
  }
  y
}

m <- 11
n <- 22
o <- 33

y <- f1(m, n, o)
z <- f2(m, n, o)

identical(y, z)
#[1] TRUE

Now test the performance.

library(microbenchmark)
library(ggplot2)

mb <- microbenchmark(
  f1 = f1(m, n, o),
  f2 = f2(m, n, o)
)

mb
autoplot(mb)

Upvotes: 1

Related Questions