Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

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.

share|improve this question
2  
It should just be $prod=V\times c$, where $c$ is a column vector, by the definition of matrix multiplication. –  Daryl Sep 21 '12 at 13:25
    
@Daryl: This gives something different; see my comment to Ed Gorcenski. –  Noah Stein Sep 21 '12 at 14:21
add comment

5 Answers

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

bsxfun(@times,V,c)
share|improve this answer
    
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. –  Wauzl Sep 21 '12 at 15:22
    
This method is as fast as using repmat. The diag-method is very slow for big n. –  Wauzl Sep 21 '12 at 15:38
    
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. –  Noah Stein Sep 21 '12 at 17:06
    
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. –  Noah Stein Sep 21 '12 at 17:08
    
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. –  Wauzl Sep 21 '12 at 17:55
add comment

A more "algebraic" way is to use:

prod=V*diag(c)

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

share|improve this answer
    
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. –  Wauzl Sep 21 '12 at 17:57
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. –  Bitwise Sep 21 '12 at 18:10
add comment
up vote 1 down vote accepted

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.

share|improve this answer
add comment

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.

share|improve this answer
    
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. –  Noah Stein Sep 21 '12 at 14:20
    
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$ –  Wauzl Sep 21 '12 at 15:11
    
@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. –  Arkamis Sep 21 '12 at 15:15
    
Still, you agree with Daryls comment. You might want to fix that, too. –  Wauzl Sep 21 '12 at 15:23
add comment

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

prod = (ones(4,1)*c).*V;
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.