R &引用;矢量化;矩阵乘法

R &引用;矢量化;矩阵乘法,r,matrix,matrix-multiplication,R,Matrix,Matrix Multiplication,假设我有两个矩阵x和y,它们的维数都是100x2。我想创建一个列表,这样对于x和y的每一行,我都有矩阵t(x)%*%y。例如,通过For循环: x = matrix(rnorm(10), nrow = 5) y = matrix(rnorm(10), nrow = 5) myList = list() for(i in 1:5){ myList[[i]] = t(x[i, , drop = FALSE]) %*% y[i, ] } 有没有更有效的方法进行此计算?我试着把它表示成矩阵乘法

假设我有两个矩阵x和y,它们的维数都是100x2。我想创建一个列表,这样对于x和y的每一行,我都有矩阵t(x)%*%y。例如,通过For循环:

x = matrix(rnorm(10), nrow = 5)
y = matrix(rnorm(10), nrow = 5)
myList = list()
for(i in 1:5){
    myList[[i]] = t(x[i, , drop = FALSE]) %*% y[i, ]
}

有没有更有效的方法进行此计算?我试着把它表示成矩阵乘法,但没有成功。我也考虑过mapply,但似乎我需要将x和y转换为向量列表而不是矩阵来使用mapply,我怀疑这是否是正确的方法。

使用
Map的单向

Map(function(x,y) matrix(x,ncol=1)%*%y ,
               split(x, row(x)), split(y, row(y))) 

似乎Map是最好的方法:

library(rbenchmark)

x = matrix(rnorm(10000), nrow = 5000)
y = matrix(rnorm(10000), nrow = 5000)
myList = list()

loopTest = function(){
    for(i in 1:nrow(x)){
        myList[[i]] = t(x[i, , drop = FALSE]) %*% y[i, ]
    }
}

loopTest2 = function(){
    for(i in 1:nrow(x)){
        myList[[i]] = outer(x[i, ], y[i, ])
    }
}

mapTest = function(){
    Map(function(x,y) matrix(x,ncol=1)%*%y ,
                   split(x, row(x)), split(y, row(y))) 
}

mapplyTest = function(){
    mapply(function(x,y) matrix(x,ncol=1)%*%y,
           x = split(x, row(x)), y = split(y, row(y))) 
}

benchmark(loopTest(), mapTest(), mapplyTest(), replications = 100)
这给了我:

test        elapsed
loopTest()   10.471
loopTest2()  12.225
mapplyTest()  3.100
mapTest()     2.252
然而,循环方法确实适用于较小的数据集,比如只有5行的数据集。

您可以使用

NewList <- list()
for (i in 1:nrow(x)) NewList[[i]] <- outer(x[i,],y[i,])
#> all.equal(NewList,myList)
#[1] TRUE

NewList我想它应该是
Map(function(x,y)matrix(x,ncol=1)%*%y,split(x,row(x)),split(y,row(y))
您应该预先分配
mylist
对象,这将使for循环方法明显更快。使用
mylist=vector(“list”,5)
尽管这可能是更干净的编码,但我无法想象这比循环快。
Map(tcrossprod,split(x,row(x)),split(y,row(y))
感谢您的测试。因此,
outer()。
for (i in 1:nrow(x)) NewList[[i]] <- x[i,] %o% y[i,]