Fastest Way for Multiplying a Matrix to a Vector

Fastest way for multiplying a matrix to a vector

sweep seems to run a bit faster on my machine

sweep(mat, 2, v, FUN = "*")

Some benchmarks:

> microbenchmark(mat %*% diag(v),sweep(mat, 2, v, FUN = "*"))

Unit: milliseconds
expr min lq median uq max neval
%*% 214.66700 226.95551 231.2366 255.78493 349.1911 100
sweep 42.42987 44.72254 62.9990 70.87403 127.2869 100

Fastest way to multiply matrix columns with vector elements in R

Use some linear algebra and perform matrix multiplication, which is quite fast in R.

eg

m %*% diag(v)

some benchmarking

m = matrix(rnorm(1200000), ncol=6)

v=c(1.5, 3.5, 4.5, 5.5, 6.5, 7.5)
library(microbenchmark)
microbenchmark(m %*% diag(v), t(t(m) * v))
## Unit: milliseconds
## expr min lq median uq max neval
## m %*% diag(v) 16.57174 16.78104 16.86427 23.13121 109.9006 100
## t(t(m) * v) 26.21470 26.59049 32.40829 35.38097 122.9351 100

Fastest way to get rowSums of multiplication of matrix by a vector in R

Even a non-vectorized solution will be faster than setting up a giant sparse matrix like you have done with diag.

system.time(
res<-sapply(v,function(v1)sum(a[v1>w]))
)
# user system elapsed
# 0.032 0.000 0.031

system.time({
m = v > rep(w, each = length(v))
dim(m)=c(length(v), length(w))
res<-rowSums(m %*% diag(a))
})
# user system elapsed
# 0.364 0.000 0.362

But, if you wanted to get fancy, you could do something like this:

fancy<-function(){
order.w<-order(w)
cumsum.a<-c(0,cumsum(a[order.w]))
cumsum.a[findInterval(v,c(-Inf,w[order.w]))]
}
system.time(res2<-fancy())
# user system elapsed
# 0 0 0
all.equal(res,res2)
# TRUE

Nice way to multiply each row of a matrix by a vector in r

I think this is what you are looking for...

t( t(mat) * vec )
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 2 3 4

* like most other operators in R is vectorised. The t is necessary because R will recycle column-wise. The apply solution is:

t( apply( mat , 1 , `*` , vec ) )
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 2 3 4

Simple and fast matrix-vector multiplication in C / C++

This is something that in theory a good compiler should do by itself, however I made a try with my system (g++ 4.6.3) and got about twice the speed on a 300x50 matrix by hand unrolling 4 multiplications (about 18us per matrix instead of 34us per matrix):

double vectors_dot_prod2(const double *x, const double *y, int n)
{
double res = 0.0;
int i = 0;
for (; i <= n-4; i+=4)
{
res += (x[i] * y[i] +
x[i+1] * y[i+1] +
x[i+2] * y[i+2] +
x[i+3] * y[i+3]);
}
for (; i < n; i++)
{
res += x[i] * y[i];
}
return res;
}

I expect however the results of this level of micro-optimization to vary wildly between systems.

Why is this naive matrix multiplication faster than base R's?

A quick glance in names.c (here in particular) points you to do_matprod, the C function that is called by %*% and which is found in the file array.c. (Interestingly, it turns out, that both crossprod and tcrossprod dispatch to that same function as well). Here is a link to the code of do_matprod.

Scrolling through the function, you can see that it takes care of a number of things your naive implementation does not, including:

  1. Keeps row and column names, where that makes sense.
  2. Allows for dispatch to alternative S4 methods when the two objects being operated on by a call to %*% are of classes for which such methods have been provided. (That's what's happening in this portion of the function.)
  3. Handles both real and complex matrices.
  4. Implements a series of rules for how to handle multiplication of a matrix and a matrix, a vector and a matrix, a matrix and a vector, and a vector and a vector. (Recall that under cross-multiplication in R, a vector on the LHS is treated as a row vector, whereas on the RHS, it is treated as a column vector; this is the code that makes that so.)

Near the end of the function, it dispatches to either of matprod or or cmatprod. Interestingly (to me at least), in the case of real matrices, if either matrix might contain NaN or Inf values, then matprod dispatches (here) to a function called simple_matprod which is about as simple and straightforward as your own. Otherwise, it dispatches to one of a couple of BLAS Fortran routines which, presumably are faster, if uniformly 'well-behaved' matrix elements can be guaranteed.

Faster way to transpose each row of a matrix and multiply the resulting vector by some other matrix?

You can use X*M.' instead of (M*X.').';. This saves around 35% of time on my computer.

This can be explained because transposing (or permuting dimensions) implies rearranging the elements in the internal (linear-order) representation of the matrix, which takes time.



Related Topics



Leave a reply



Submit