R 两个矩阵的部分积
我试图找到一种矢量化技巧来计算两个矩阵的行R 两个矩阵的部分积,r,matrix,R,Matrix,我试图找到一种矢量化技巧来计算两个矩阵的行I和列I之间的乘积,而不会在其他乘积(行I和列j,I!=j)上浪费资源 这个怎么样 mapply(crossprod, as.data.frame(t(A)), as.data.frame(B)) 行和(A*t(B))似乎非常快: A <- matrix(rnorm(400*500), nrow=400) B <- matrix(rnorm(500*400), ncol=400) bF <- function() diag(A %*
I
和列I
之间的乘积,而不会在其他乘积(行I和列j,I!=j)上浪费资源
这个怎么样
mapply(crossprod, as.data.frame(t(A)), as.data.frame(B))
行和(A*t(B))
似乎非常快:
A <- matrix(rnorm(400*500), nrow=400)
B <- matrix(rnorm(500*400), ncol=400)
bF <- function() diag(A %*% B)
jF <- function() rowSums(A * t(B))
vF <- function() mapply(crossprod, as.data.frame(t(A)), as.data.frame(B))
lF <- function() {
vec <- numeric(nrow(A))
for (ii in seq.int(nrow(A)))
vec[ii] <- crossprod(A[ii,], B[,ii])
vec
}
library(microbenchmark)
microbenchmark(bF(), jF(), vF(), lF(), times = 100)
# Unit: milliseconds
# expr min lq median uq max neval
# bF() 137.828993 183.320782 185.823658 200.747130 207.67997 100
# jF() 4.434627 5.300882 5.341477 5.475393 46.96347 100
# vF() 39.110948 51.071936 54.147338 55.127911 102.17793 100
# lF() 14.029454 18.667055 18.931154 22.166137 65.40562 100
A恐怕效率相当低;mapply是for循环的包装器,data.frames的访问速度通常比Matrices慢很多。顺便说一句,我看不出for循环有什么问题。[]
对于矩阵应该没有什么开销;最后我会在C++中做这个,循环不再重要,除了文盲。好主意!特别是我不需要转置,我可以用正确的形式构造B,这是一个好主意!您还可以添加一个与显式for循环的比较吗?
mapply(crossprod, as.data.frame(t(A)), as.data.frame(B))
A <- matrix(rnorm(400*500), nrow=400)
B <- matrix(rnorm(500*400), ncol=400)
bF <- function() diag(A %*% B)
jF <- function() rowSums(A * t(B))
vF <- function() mapply(crossprod, as.data.frame(t(A)), as.data.frame(B))
lF <- function() {
vec <- numeric(nrow(A))
for (ii in seq.int(nrow(A)))
vec[ii] <- crossprod(A[ii,], B[,ii])
vec
}
library(microbenchmark)
microbenchmark(bF(), jF(), vF(), lF(), times = 100)
# Unit: milliseconds
# expr min lq median uq max neval
# bF() 137.828993 183.320782 185.823658 200.747130 207.67997 100
# jF() 4.434627 5.300882 5.341477 5.475393 46.96347 100
# vF() 39.110948 51.071936 54.147338 55.127911 102.17793 100
# lF() 14.029454 18.667055 18.931154 22.166137 65.40562 100