Multiply matrix rows by vector?

I am optimizing a function and I want to get rid of slow loops. I am looking for a faster way to multiply each row of a matrix by a vector.

Any ideas?

EDIT:

I am not looking for "classic" multiplication.

Eg. I have a matrix that has 23 columns and 25 rows and a vector of length 23. As a result, I want to have a 25x23 matrix that has each row times the vector.

+61
vector matrix r multiplication
04 Sep '10 at 18:51
source share
5 answers

I think you are looking for 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 

This was one of the core functions of R, although improvements have been made over the years.

+66
Sep 06 '10 at 9:52
source share
— -
 > 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 

You can use either:

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

or

 > MyMatrix %*% diag(MyVector) [,1] [,2] [,3] [1,] 1 4 9 [2,] 11 24 39 
+35
Sep 04 '10 at 19:06
source share

In fact, sweep not the fastest option on my computer:

 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 

This gives:

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

As the slowest option, the second option reaches the memory limit (2046 MB). However, given the remaining options, double transposition, in my opinion, is much better than sweep .




Edit

Just repeat less data a few times:

 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 
+23
Sep 21 '10 at 19:46
source share

For speed, you can create a matrix from a vector before multiplication

 mat <- matrix(rnorm(1e6), ncol=1e4) vec <- c(1:1e4) mat * matrix(vec, dim(mat)[1], length(vec)) library(microbenchmark) microbenchmark( transpose = t(t(mat) * vec), make_matrix = mat * matrix(vec, dim(mat)[1], length(vec), byrow = TRUE), sweep = sweep(mat,MARGIN=2,vec,'*')) #Unit: milliseconds # expr min lq mean median uq max neval # transpose 10.554500 11.459181 14.344774 11.917376 16.235005 86.74867 100 # make_matrix 4.104297 4.537571 6.338247 4.767895 8.537845 13.52492 100 # sweep 8.332441 8.743813 13.396708 9.175766 14.843811 83.42181 100 
+1
Dec 01 '18 at 14:38
source share

Google "R matrix multipcation" gives "Matrix Multiplication" , which describes the% *% operator and says: "Multiplies two matrices if they If one argument is a vector, it will be assigned either a matrix of rows or columns to make two arguments compatible If both of them are vectors, it will return the inner product (in the form of a matrix).

-2
Sep 04 '10 at 19:18
source share



All Articles