1
$\begingroup$

This sounds a bit strange, I'll explain it further. Assume we have a row vector $c = (c_1,c_2,\dots,c_n)$ and we have $n$ column vectors $v_i\in\mathbb R^4$ for $i\in\{1,\dots,n\}$. The $c$ is stored in Matlab as as vector c = [c1 c2 c3 ... cn] and the vectors $v_i$ are stored in a matrix V = [v1 v2 v3 ... vn].

I want now to calculate the matrix $(c_1 v_1, c_2 v_2, \dots, c_n v_n)$ in Matlab. This can be done easily by

for i = 1:n    prod(1:4,i) = c(i)*V(:,i); end 

But I want it to do without any for loop and without any repmat-command as its rather slow this way.

  • 0
    @Daryl: This gives something different; see my comment to Ed Gorcenski.2012-09-21

5 Answers 5

0

I just figured out a faster way (with a little help from my friends):

prod = (ones(4,1)*c).*V; 
1

I'm not sure whether this is on-topic for this site, but the command you want is:

bsxfun(@times,V,c) 
  • 0
    Yes, I will of course put a comment near this. My little test program told me that using repmat was as fast as using bsxfun, even for big matrices. Although it might take more RAM, but I'm not sure about that. I prefer your solution, though.2012-09-21
1

A more "algebraic" way is to use:

prod=V*diag(c) 

where diag(c) creates a diagonal matrix with c on its diagonal

  • 1
    Yes, you should definitely use a sparse diagonal. In any case bsxfun could be faster (not sure though). My point was just to show that you can do this with normal matrix multiplication.2012-09-21
1

I just figured out an even faster way (with a little help from my friends) and I think this might be the fastest way to do this in Matlab:

prod = c(ones(4,1),:).*V; 

Despite c beeing a vector, it can be treated as a matrix, also. The code c(ones(4,1),:) produces the same output as repmat(c,4,1), only faster.

0

Daryl's comment is mostly correct, except instead of transpose you need the diagonal operator on $c$. In MATLAB notation, prod = V*diag(c); for c being defined as a row vector. I will elaborate why.

$V = \begin{pmatrix} v_{11} & v_{12} & \cdots & v_{1n} \\ v_{21} & v_{22} & \cdots & v_{2n} \\ \vdots & & \ddots & \vdots \\ v_{m1} & v_{m2} & \cdots & v_{mn}\end{pmatrix}$ $ c = \begin{pmatrix} c_1 & c_2 & \cdots & c_n\end{pmatrix} $

Then,

$V*\mathrm{diag}(c) = \begin{pmatrix} v_{11} & v_{12} & \cdots & v_{1n} \\ v_{21} & v_{22} & \cdots & v_{2n} \\ \vdots & & \ddots & \vdots \\ v_{m1} & v_{m2} & \cdots & v_{mn}\end{pmatrix} \begin{pmatrix} c_1 & 0 & 0 & 0\\ 0 & c_2 & 0 & 0 \\ 0 & 0 & \ddots & 0 \\ 0 & 0 & 0 &c_n\end{pmatrix} = \begin{pmatrix} c_1v_{11} & c_2v_{12} & \cdots & c_nv_{1n} \\ c_1v_{21} & c_2v_{22} & \cdots & c_nv_{2n} \\ \vdots & & \ddots & \vdots \\ c_1v_{m1} & c_2v_{m2} & \cdots & c_nv_{mn} \end{pmatrix}$

Which is exactly what you want.

  • 0
    Still, you agree with Daryls comment. You might want to $f$ix that, too.2012-09-21