Suppose I have the following 2 matrices
A <- matrix(nrow = 5, ncol = 3, byrow = TRUE, c(
5, 1, 2,
3, 1, 5,
5, 1, 3,
7, 2, 8,
2, 4, 2
))
B <- matrix(nrow = 5, ncol = 2, byrow = TRUE, c(
2, 1,
3, 5,
1, 4,
3, 3,
3, 4
))
and I want to create an array
arr <- array(NA, dim = c(ncol(A), ncol(B), nrow(A)))
to store the cross product of row i
of matrix A
with the same row i
of matrix B
. For example, slice 2 of arr
would be
A[2, ] %*% t(B[2, ]
[,1] [,2]
[1,] 9 15
[2,] 3 5
[3,] 15 25
Using a for loop, I can do
for (i in 1:nrow(A)) {
arr[, , i] <- A[i, ] %*% t(B[i, ])
}
Or using an sapply
function
temp <- sapply(1:nrow(A), function(i) A[i, ] %*% t(B[i, ]), simplify = FALSE)
arr <- array(unlist(temp), dim = c(ncol(A), ncol(B), nrow(A)))
I am wondering if there is more clever way using matrix products or built-in functions in this case. Thank you so much.
CodePudding user response:
Using einstein summation notation
library(einsum)
arr2 <- einsum("ij,ik->jki", A, B)
identical(arr2, arr)
## [1] TRUE
CodePudding user response:
We can try base R option with mapply
tcrossprod
like below
array(
mapply(tcrossprod, asplit(A, 1), asplit(B, 1)),
c(ncol(A), ncol(B), nrow(A))
)