2

Say I have two three dimensional arrays and I would like the sum of the products of the arrays based on one of the indices. What I would like is that sum in the the last line of the example code below. I know I can use a loop but I'd like to do this in an efficient way, hoping that there is some R function that does something like this. Any help would be greatly appreciated.

a <- array(1:12, dim=c(3, 2, 2))
b <- array(1, dim=c(3, 2, 2))
a[1, , ] %*% t(b[1, , ]) + a[2, , ] %*% t(b[2, , ]) + a[3, , ] %*% t(b[3, , ])
statsgrad1990
  • 89
  • 1
  • 3

1 Answers1

2

Unless you actually experience serious inefficiency issues then do it with a for loop. You can't really use the built-in apply on two objects. (See comment)

Note that apply isn't guaranteed to be faster than regular for loops.

EDIT: As a result of the comments:

Reduce(`+`, lapply(1:dim(a)[1], function(i) a[i, , ] %*% t(b[i, , ])))

is a potential solution with applies. Though I doubt it is more efficient than a straight forward

sum <- matrix(0, ncol = dim(a)[2], nrow =  dim(a)[2])
for (i in 1: dim(a)[1]) sum <- sum + a[i, , ] %*% t(b[i, , ])

which I think is much clearer in what its trying to do.

shians
  • 955
  • 1
  • 6
  • 21
  • No, but you can use `Map` or `mapply` - but you are right the speed is not going to change much. – thelatemail Apr 27 '17 at 00:39
  • Ah yes, sorry for the misinformation, never used that part of the apply family. Though mapply probably still isn't directly applicable here and returns a list which may have more overhead than is worthwhile for efficiency. – shians Apr 27 '17 at 01:00
  • It's arguably harder to read than a loop, but doable - `Reduce(\`+\`, Map(function(x,y) a[x,,] %*% t(b[y,,]), seq_len(dim(a)[1]), seq_len(dim(b)[1])))` – thelatemail Apr 27 '17 at 01:06
  • I think at that point you might as well do `Reduce(\`+\`, lapply(1:dim(a)[1], function(i) a[i, , ] %*% t(b[i, , ])))`. I'm pretty sure at least a few of these are just wrappers over for loops anyway. – shians Apr 27 '17 at 02:00
  • true - you should add that as an answer - seems about as simple as it will get. – thelatemail Apr 27 '17 at 02:07