После моего комментария, вот метод с пакетом matrixStats
и outer
для выполнения расчета.
# nested loop
mat1 <-
do.call('cbind', lapply(1:5, function(i) {
sapply(1:5, function(j) {
prod(a[i,] * b[,j])
})
}))
# vectorized-ish
library(matrixStats)
mat2 <- outer(colProds(b), rowProds(a))
Теперь проверьте, что они численно эквивалентны.
all.equal(mat1, mat2)
[1] TRUE
Если вы хотите внешний вид %*%
, вы можете изменить это на
mat2 <- colProds(b) %o% rowProds(a)
Вы можете придерживаться базы R, если хотите избежать посылок. Вот один из методов.
mat3 <- outer(
vapply(seq_len(ncol(b)), function(x) prod(b[, x]), numeric(1L)),
vapply(seq_len(nrow(a)), function(x) prod(a[x, ]), numeric(1L))
))
проверяя скорость этих двух, я получаю следующее
library(microbenchmark)
microbenchmark(nest=
do.call('cbind', lapply(1:5, function(i) {
sapply(1:5, function(j) {
prod(a[i,] * b[,j])
})
})),
vect=outer(colProds(b), rowProds(a)),
baseVect=outer(
vapply(seq_len(ncol(b)), function(x) prod(b[, x]), numeric(1L)),
vapply(seq_len(nrow(a)), function(x) prod(a[x, ]), numeric(1L))
))
Unit: microseconds
expr min lq mean median uq max neval
nest 129.228 133.2225 172.43874 136.833 142.9640 3531.144 100
vect 23.831 25.8690 28.38306 27.705 29.1815 94.546 100
baseVect 27.223 29.8970 57.85946 31.471 32.8400 2647.373 100