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.

  • 2
    It should just be $prod=V\times c$, where $c$ is a column vector, by the definition of matrix multiplication.2012-09-21
  • 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
    I don't think this is off-topic, it seems to be what I was looking for, actually. But it's rather hard to read. I'm going to test all the possibilities to tell which method does it faster.2012-09-21
  • 0
    This method is as fast as using repmat. The diag-method is very slow for big n.2012-09-21
  • 0
    I believe this method is recommended over repmat for large matrices because MATLAB doesn't have to allocate all that extra memory or copy the data over.2012-09-21
  • 0
    But it is sometimes considered good style to put a comment nearby containing one of the other more, readable answers so people know what the line is supposed to do.2012-09-21
  • 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

  • 0
    Thank you, but this solution is horribly slow for big $n$, because a diagonal matrix of size $n\times n$ has to be created. Maybe with a sparse diag it is faster.2012-09-21
  • 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
    This is incorrect because matrix multiplication $Vc^T$ will give you an $m\times 1$ vector whose components are the sums of the components of the $m\times n$ matrix you have written on the right hand side.2012-09-21
  • 0
    Noah Stein ist right, because with matrix multiplication what I get by $V c^T$ is $\left(\sum_{k=1}^n c_k v_{ik})\right)_{i=1}^n$2012-09-21
  • 0
    @NoahStein Er right, I got so carried away with typsetting the matrix that I forgot to mention it needs to be the diag(c), not transpose of c. Thanks for the catch! I've fixed it.2012-09-21
  • 0
    Still, you agree with Daryls comment. You might want to fix that, too.2012-09-21