用矢量乘以矩阵行?

我正在优化一个函数,我想摆脱慢循环。 我正在寻找一种更快的方法来将矩阵的每一行乘以一个向量。

有任何想法吗?

编辑:

我不是在寻找一种“古典”的乘法。

例如。 我有矩阵,有23列和25行,矢量的长度为23.结果我想要矩阵25x23,每行乘以矢量。


我认为你正在寻找sweep()

> (mat <- matrix(rep(1:3,each=5),nrow=3,ncol=5,byrow=TRUE))
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
> vec <- 1:5
> sweep(mat,MARGIN=2,vec,`*`)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    2    4    6    8   10
[3,]    3    6    9   12   15

这是R的核心功能之一,尽管多年来已经有所改进。


> MyMatrix <- matrix(c(1,2,3, 11,12,13), nrow = 2, ncol=3, byrow=TRUE)
> MyMatrix
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]   11   12   13
> MyVector <- c(1:3)
> MyVector
[1] 1 2 3

你可以使用:

> t(t(MyMatrix) * MyVector)
     [,1] [,2] [,3]
[1,]    1    4    9
[2,]   11   24   39

要么:

> MyMatrix %*% diag(MyVector)
     [,1] [,2] [,3]
[1,]    1    4    9
[2,]   11   24   39

实际上, sweep并不是我电脑上的最快选项:

MyMatrix <- matrix(c(1:1e6), ncol=1e4, byrow=TRUE)
MyVector <- c(1:1e4)

Rprof(tmp <- tempfile(),interval = 0.001)
t(t(MyMatrix) * MyVector) # first option
Rprof()
MyTimerTranspose=summaryRprof(tmp)$sampling.time
unlink(tmp)

Rprof(tmp <- tempfile(),interval = 0.001)
MyMatrix %*% diag(MyVector) # second option
Rprof()
MyTimerDiag=summaryRprof(tmp)$sampling.time
unlink(tmp)

Rprof(tmp <- tempfile(),interval = 0.001)
sweep(MyMatrix ,MARGIN=2,MyVector,`*`)  # third option
Rprof()
MyTimerSweep=summaryRprof(tmp)$sampling.time
unlink(tmp)

Rprof(tmp <- tempfile(),interval = 0.001)
t(t(MyMatrix) * MyVector) # first option again, to check order 
Rprof()
MyTimerTransposeAgain=summaryRprof(tmp)$sampling.time
unlink(tmp)

MyTimerTranspose
MyTimerDiag
MyTimerSweep
MyTimerTransposeAgain

这产生:

> MyTimerTranspose
[1] 0.04
> MyTimerDiag
[1] 40.722
> MyTimerSweep
[1] 33.774
> MyTimerTransposeAgain
[1] 0.043

除最慢选项之外,第二个选项达到内存限制(2046 MB)。 然而,考虑到其余的选择,在我看来,双重换位看起来好于sweep


编辑

只需重复尝试较小的数据:

MyMatrix <- matrix(c(1:1e3), ncol=1e1, byrow=TRUE)
MyVector <- c(1:1e1)
n=100000

[...]

for(i in 1:n){
# your option
}

[...]

> MyTimerTranspose
[1] 5.383
> MyTimerDiag
[1] 6.404
> MyTimerSweep
[1] 12.843
> MyTimerTransposeAgain
[1] 5.428
链接地址: http://www.djcxy.com/p/85981.html

上一篇: Multiply rows of matrix by vector?

下一篇: Multiply a 3D matrix with a 2D matrix