Multiplique linhas de matriz por vetor?

Estou otimizando uma function e quero me livrar de loops lentos. Estou procurando uma maneira mais rápida de multiplicar cada linha de uma matriz por um vetor.

Alguma ideia?

EDITAR:

Eu não estou procurando por uma multiplicação ‘clássica’.

Por exemplo. Eu tenho matriz que tem 23 colunas e 25 linhas e um vetor que tem comprimento 23. Em um resultado eu quero ter matriz 25×23 que tem cada linha multiplicada por vetor.

Eu acho que você está procurando por 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 

Tem sido uma das principais funções do R, embora melhorias tenham sido feitas ao longo dos anos.

 > 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 

Você poderia usar:

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

ou:

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

Na verdade, a sweep não é a opção mais rápida no meu computador:

 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 

Isso produz:

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

Além de ser a opção mais lenta, a segunda opção atinge o limite de memory (2046 MB). No entanto, considerando as restantes opções, a dupla transposição parece muito melhor do que a sweep na minha opinião.


Editar

Apenas tentando dados menores um número repetido de vezes:

 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